模拟SpringIOC 思路分析

模拟Spring IOC 思路分析:

参考: www.mayikt.com

步骤1: Bean定义注册 BeanDefinitionRegister
Bean定义注册放入到BeanDefinitionMap中🔑 类名首字母小写 value: class
ApplicationContext上下文构造方法传递配置类,配置类上扫包范文;
—>得到配置从而得到扫包范围[ClassUtils工具类] 得到class信息

步骤2:注册BeanPostProcessors

步骤3:提前初始化Bean单例对象 beanFactory.preInstantiateSingletons();
[在BeanFactory中定义初始化单例对象(需要结合Bean后置处理器对属性赋值(属性也需要初始化)]

(1)Bean 对象的描述: BeanDefinition 对象
public class CustomBeanDefinition{
private String beanName;
private Class<?> beanClass;
private String scope;

//setXxx /getXxx 方法

}

(2)CustomBeanFactory Bean工厂定义 [工厂模式]
public class CustomBeanFactory{

//存放 beanDefinitionMap 存放解析的Bean定义
private static Map<String, CustomBeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(16);
//存放单例池对象 
private static Map<String, Object> singletonMap = new HashMap<>(16);
//后置处理器
private List<CustomBeanPostProcessor> beanPostProcessor = new ArrayList<>();

}

(3)CustomApplicationContext extends CustomBeanFactory 对BeanFactory进行增强 [采用继承模式增强]
创建上下文对象的时候需要传递一个配置类,解析扫描范围,
刷新方法功能:扫描、添加bean处理器、提前调用单例池
refresh():
// 执行bean工厂处理器完成扫包工作,注册Bean定义信息
invokeBeanFactoryPostProcessors(beanFactory);
//注册后置处理器 在BeanFactory中 添加,子类调用
registerBeanPostProcessors();
//提前初始化Bean对象
preInstantiateSingletons();

(4)遍历bean定义Map,创建bean对象(通过反射)放入单例池中。createBean();
⑤反射实例化,放入到单例池
②属性赋值(依赖注入@Autowired) 通过后置处理器AutowiredAnnotationBeanPostProcessor
-extends->InstantiationAwareBeanPostProcessorAdapter
–implements–>SmartInstantiationAwareBeanPostProcessor
–implements–> InstantiationAwareBeanPostProcessor
-extends-> BeanPostProcessor

3.属性的初始化

[
开发者自定义Bean处理器实现BeanPostProcessor在初始化前后执行
实现InstantiationAwareBeanPostProcessor 该接口的后置处理器在属性赋值阶段执行
]
populateBean();//属性数值 通过Autowired后置处理,如何关联进行调用的?
提前注册添加好后置处理器,循环遍历,判断是否实现InstantiationAwareBeanPostProcessor该接口
如果实现了该接口会提前执行属性赋值的方法:
(1)利用java反射机制获取到Bean类中成员属性
(2)判断属性上是否加上@Autowired注解,如果加上,根据类型或者名称从IOC容器中获取bean对象。
然后利用反射机制赋值,方法上通过参数把BeanFactory传递给后置处理器
(3)通过BeanFactory 根据名称或者类型从IOC容器中查找.

如何查找?需要考虑如果依赖的属性不存在了,那么又要走createBean()方法了,那么代码怎么写?
1.先从单例池中查找,如果有返回
2.如果没有,根据bean名称或者类型从BeanDefinitionMap中获取BeanDefinition信息,如果没有获取到BeanDefintion信息抛出异常。
3.得到BeanDefinition信息,调用createBean方法.返回创建的对象 [暂时不考虑循环问题]
4.需要注意在反射前先从单例池获取一下,看是否存在。存在返回,不存在再进行反射。

【因为A–>B ; B -->A ,在创建Bean的时候要考虑这种循环依赖】

实例化完之后,依赖赋值,然后进行初始化,初始化的后置处理器,在初始化前后执行操作

4.执行Aware回调方法
invokeAwareMethods(refBean,beanName);

  1. bean 处理器初始化方法之前执行
    applyBeanPostProcessorsBeforeInitialization(refBean,beanName);

  2. 执行初始化方法 实现InitializingBean接口
    invokeInitMethods(refBean);

  3. Bean处理器初始化方法之后执行
    applyBeanPostProcessorsAfterInitialization(refBean,beanName);

初始化后置处理器如何实现调用?

private void invokeAwareMethods(Object refBean,String beanName){
if(refBean instanceof BeanNameAware){
BeanNameAware beanNameAware = (BeanNameAware)refBean;
beanNameAware.setBeanName(beanName);
}
}

处理器调用,提前创建好。判断实现哪种后置处理器,然后在调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值