扫描类
这个类就不多说了,基本所有框架都要有这一步,这里主要关注我们目前要实现的方法,其他的具体方法可以查看源码
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.调用扫描类,加载所有beanBeanScanner 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.判断是否有Componentfor (String name : allJavaFile) {if (beanScanner.isComponent(name)) {// 3.是Component就开始bean的生命周期Class<?> clazz = beanScanner.getClazz(name);// 创建beanObject 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;}
测试结果
可以看到我们成功的给对象赋值了