手写高仿真Spring框架
流行词:顶层设计 依赖注入
参考代码:https://gitee.com/li-lixiang/lean-spring-2.0.git
在上衣篇blog中,已经实现Spring IOC容器的初始化,接下来对伪容器(真正的容器时保存BeanWrapper对象的)中的类名,进行实例注入(非延时加载)。也就是完成依赖注入。
依赖注入
- 初始化(实例化)
- 通过读取伪容器中的BeanDefinition对象,获取类信息,从而通过反射机制进行实例化对象。
- 而Spring的做法非此直接,而是用到BeanWrapper对象进行一次包装。再将BeanWrapper对象存到真的IOC容器中。
- 注入(单例,多例的处理,相互依赖的情况处理BeanWrapper包装器模式处理)
初始化
- 拿到需要实例化的对象
- 反射实例化,得到一个对象
- 将实例化对象通过BeanWrapper封装
- 将封装的BeanWrapper对象,缓存到factoryBeanObjectCache
private Object instantiateBean(String beanName, GPBeanDefinition gpBeanDefinition) {
//1、拿到要实例化的对象的类名
String className = gpBeanDefinition.getBeanClassName();
//2、反射实例化,得到一个对象
Object instance = null;
try {
// gpBeanDefinition.getFactoryBeanName()
//假设默认就是单例,细节暂且不考虑,先把主线拉通
if(this.factoryBeanObjectCache.containsKey(className)){
instance = this.factoryBeanObjectCache.get(className);
}else {
Class<?> clazz = Class.forName(className);
instance = clazz.newInstance();
GPAdvisedSupport config = instantionAopConfig(gpBeanDefinition);
config.setTargetClass(clazz);
config.setTarget(instance);
//符合PointCut的规则的话,闯将代理对象
if(config.pointCutMatch()) {
instance = createProxy(config).getProxy();
}
this.factoryBeanObjectCache.put(className,instance);
this.factoryBeanObjectCache.put(gpBeanDefinition.getFactoryBeanName(),instance);
}
}catch (Exception e){
e.printStackTrace();
}
return instance;
}
注入
- 判断只有加了注解的类,才执行依赖注入
- 获得所有的fields,然后对其处理,对所有需要依赖注入的fields,也就是将factoryBeanObjectCache中获取实例化的对象进行注入
private void populateBean(String beanName, GPBeanDefinition gpBeanDefinition, GPBeanWrapper gpBeanWrapper) {
Object instance = gpBeanWrapper.getWrappedInstance();
// gpBeanDefinition.getBeanClassName();
Class<?> clazz = gpBeanWrapper.getWrappedClass();
//判断只有加了注解的类,才执行依赖注入
if(!(clazz.isAnnotationPresent(GPController.class) || clazz.isAnnotationPresent(GPService.class))){
return;
}
//获得所有的fields
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if(!field.isAnnotationPresent(GPAutowired.class)){ continue;}
GPAutowired autowired = field.getAnnotation(GPAutowired.class);
String autowiredBeanName = autowired.value().trim();
if("".equals(autowiredBeanName)){
autowiredBeanName = field.getType().getName();
}
//强制访问
field.setAccessible(true);
try {
//为什么会为NULL,先留个坑
if(this.factoryBeanInstanceCache.get(autowiredBeanName) == null){ continue; }
// if(instance == null){
// continue;
// }
field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName).getWrappedInstance());
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}