扫描类
这个类就不多说了,基本所有框架都要有这一步,这里主要关注我们目前要实现的方法,其他的具体方法可以查看源码
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;
}
测试结果
可以看到我们成功的给对象赋值了