今天来一起揭秘下spring的AOP的代理对象是如何交由IOC容器管理的;
首先先梳理IOC容器创建bean的整个过程:
1,通过读取xml,或者注解来注册我们程序所需要的交由spring管理的bean信息;比如在某个类上面加上@Component注解
2,解析相关的元素信息加载到BeanDefinition中,在BeanFactory容器以Key为beanName,Value为bean对应的BeanDefinition的Map存放我们所定义的相关信息如类名,实例类型,属性等;
3,循环获取所有的Map中的bean定义信息,开始实例化;
4,首先判断Map :SingletonObjects中是否存在该单例,这里如果存在属性循环依赖,将从三级缓存SingletonFactories中拿到对应的工厂获取对应已实例化但未初始化的依赖,并且放置到二级缓存 earlySingletonObject中,并且删除三级缓存;
5,通过BeanPostProcessor决定采用哪种方式实例化.也就是通过构造器或者反射的方式newInstant;
6,实例化后,判断是否支持循环依赖,然后将当前实例化的bean放置到SingletonFactory中,如果存在循环依赖时,便走了4步骤的情况;
7,通过BeanPostProcessor处理属性值;
8,调用所有BeanPostProcessor前置方法,完成初始化之前的一些设置;
9,执行初始化的方法,也就是执行我们程序使用的@PostConstruct 或者实现InitailizingBean 的afterPropertiesSet接口的方法;
10,调用所有的BeanPostProcessor后置方法,完成初始化之后的一些设置;
11,如果配置了销毁方法,最后还会注册对应的bean信息,放置到disposableBeans的Map中,等到实例销毁时执行;
了解了整个bean的大致加载过程;我们来看看什么时候Spring会把原生的bean转化成代理对象?
Spring提供了的BeanPostProcessor接口可以在bean的整个实例初始化过程中添加各种定制化逻辑,而AOP的代理就是在
BeanPostProcessor 的后置方法中实现的。
通常情况下,在上述bean创建过程中的第10步,调用所有的后置处理器的后置方法中,AOP的动态代理的创建在AbstractAutoProxyCreator的postProcessAfterInitialization方法中实现;
当存在属性循环依赖,且是依赖是代理对象时,代理对象会被提前创建。
postProcessAfterInitialization方法中先在earlyProxyReferences的Map中拿到是否已经先被提前创建了代理对象。如果创建好了就不需要再创建代理对象了,直接得到缓存的对象。什么情况下会提前创建代理对象呢?
当A依赖B,B依赖A 而A属于一个需要被代理的对象时,因为B注入A属性时,应该得到一个代理对象。所以在用SingletonFatory.getBean()时,要获取一个代理对象;这时Spring会提前创建代理对象然后放到缓存里。流程如下: