【仿写spring之ioc篇】二、bean生命周期中的创建以及属性赋值

扫描类

这个类就不多说了,基本所有框架都要有这一步,这里主要关注我们目前要实现的方法,其他的具体方法可以查看源码

isComponent方法

	/**
     * 扫描所有带有@Component注解的java类,放入到BeanRegistry
     *
     * @return boolean
     */
    public boolean isComponent(String name) throws ClassNotFoundException, NoSuchMethodException {
        Class<?> clazz = Class.forName(name);
        Component annotation = clazz.getAnnotation(Component.class);
        return annotation != null;
    }

getValuedField方法

	/**
     * 获取有value注解的属性
     *
     * @param clazz
     * @return {@link List}<{@link Field}>
     */
    public List<Field> getValuedField(Class<?> clazz){
        List<Field> valuedFieldList = new ArrayList<>();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Value annotation = declaredField.getAnnotation(Value.class);
            if (annotation != null){
                valuedFieldList.add(declaredField);
            }
        }
        return valuedFieldList;
    }

工厂类

这个类目前就是用来管理所有的bean对象,存放方式是map,key是beanName,value是bean对象。需要注意的就是扫描到@Value注解时的处理方法,需要通过拼接set的形式来实现

package com.ez4sterben.spring.ioc.factory.support;

import com.ez4sterben.spring.ioc.annotation.Value;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * bean工厂,储存所有的bean对象
 *
 * @author ez4sterben
 * @date 2023/08/31
 */
public class BeanFactory {

    /**
     * 储存bean实例
     */
    private final Map<String, Object> beanMap = new HashMap<>(256);

    /**
     * 创建bean
     *
     * @param beanClass
     * @return {@link T}
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public <T> T createBean(Class<T> beanClass) throws InstantiationException, IllegalAccessException {
        return beanClass.newInstance();
    }

    /**
     * 调用set方法
     *
     * @param object
     * @param valuedField
     * @return {@link Object}
     */
    public Object doSet(Object object, List<Field> valuedField) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> clazz = object.getClass();
        for (Field field : valuedField) {
            Value annotation = field.getAnnotation(Value.class);
            String value = annotation.value();
            Method method = clazz.getMethod(parseSetter(field.getName()),String.class);
            method.invoke(object,value);
        }
        return object;
    }

    /**
     * 解析set方法
     * @param fieldName
     * @return {@link String}
     */
    public String parseSetter(String fieldName){
        String substring = fieldName.substring(0, 1);
        String s = substring.toUpperCase();
        return "set" + s + fieldName.substring(1);
    }
}

启动类

启动类中打印一下调用赋值方法之后的bean对象看一下效果

package com.ez4sterben.spring.test;

import com.ez4sterben.spring.ioc.annotation.BeanScanner;
import com.ez4sterben.spring.ioc.factory.aware.ApplicationContextAware;
import com.ez4sterben.spring.ioc.factory.aware.BeanFactoryAware;
import com.ez4sterben.spring.ioc.factory.aware.BeanNameAware;
import com.ez4sterben.spring.ioc.factory.support.BeanFactory;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 主要
 *
 * @author ez4sterben
 * @date 2023/09/01
 */
public class Main {

    public static void main(String[] args) throws Exception {
        // 1.调用扫描类,加载所有bean
        BeanScanner beanScanner = new BeanScanner();
        BeanFactory beanFactory = new BeanFactory();
        List<String> allJavaFile = beanScanner.getAllJavaFile("F:\\projects\\gitProject\\spring-all\\src\\main\\java\\com\\ez4sterben\\spring\\test");
        // 2.判断是否有Component
        for (String name : allJavaFile) {
            if (beanScanner.isComponent(name)) {
                // 3.是Component就开始bean的生命周期
                Class<?> clazz = beanScanner.getClazz(name);
                // 创建bean
                Object bean = beanFactory.createBean(clazz);
                // 查看@Value注解
                // 1.找到所有@Value的字段
                List<Field> valuedField = beanScanner.getValuedField(clazz);
                // 2.调用set方法
                beanFactory.doSet(bean, valuedField);
                System.out.println(bean);
                // Aware
                // 1.检查是否实现了Aware接口
                // BeanNameAware

                // BeanFactoryAware

                // ApplicationContextAware

                // BeanPostProcessor

                // @PostConstruct

                // InitializingBean

                // BeanPostProcessor

                // using
            }
        }

    }
}

测试类

package com.ez4sterben.spring.test;

import com.ez4sterben.spring.ioc.annotation.Component;
import com.ez4sterben.spring.ioc.annotation.Value;
import com.ez4sterben.spring.ioc.factory.aware.BeanNameAware;
import lombok.Data;

/**
 * 测试组件
 *
 * @author ez4sterben
 * @date 2023/09/01
 */
@Component
@Data
public class TestComponent implements BeanNameAware {
    @Value("ez4sterben")
    private String name;
    private String age;

}

测试结果

【仿写spring之ioc篇】二、bean生命周期中的创建以及属性赋值_第1张图片
可以看到我们成功的给对象赋值了

你可能感兴趣的:(源码仿写,spring,java,反射,代理)