spring ioc容器之Bean实例化和依赖注入
spring中的bean对象和java对象是有些许差别的,spring中的bean包含了java对象,并且是基于java对象在spring中做了一些列的加工,所以说spring中的bean比java对象更加丰富。在spring中bean的实例化有2个时机:
下面从spring ioc容器初始化的时候,预实例化的bean为线索来追溯bean的实例化和依赖注入过程,这个过程涵盖了getBean方法。
在spring ioc容器初始化的时候,触发了所有预实例化的bean的加载,这里必须是非抽象、单例和非懒加载的bean才符合条件进行预实例化。具体bean的实例化是在getBean方法中。
这里通过getSingleton先从缓存中获取bean实例。
从缓存中获取很好理解,分别从spring容器的一级缓存singletonObjects、二级缓存earlySingletonObjects和三级缓存singletonFactories中获取bean实例。在初次获取bean的时候,这里的缓存肯定为空的,但是对于存在循环依赖的bean,这里的一级或二级缓存就不是空的。在有循环依赖的bean中,这里一级缓存会存在不为空的情况,这个时候通过singletonFactory.getObject的时候,返回的可能是一个bean实例,也有可能是一个提前进行aop的代理对象( 正常情况下aop是发生在bean初始化的时候完成的 ),对于有循环依赖并且需要进行aop的bean,在这里会进行提前aop代理对象的生成。
当缓存中没有找到bean实例的时候:
通过singletonFactory.getObject回调前面的createBean方法获取bean实例,然后对于是新创建的bean实例添加到spring容器中的一级缓存singletonObjects中。下面从createBean中看bean是如何实例化的。
在这里可以看到整个bean实例化的全貌,也可以看出bean在spring中的生命周期:
可以看到在spring中是通过SimpleInstantiationStrategy类来进行bean对象的创建,有java反射和cglib两种方式进行bean的创建,判断依据是,在BeanDefinition中有动态代理或增强的时候会用cglib去创建bean对象。
根据bean是单例,并且当前bean是在创建中的时候,会去添加一个ObjectFactory到spring容器的三级缓存singletonFactories中。这里会有可能提前进行aop代理对象的生成。
这里把一个ObjectFactory添加到spring容器的三级缓存中去,在前面通过缓存获取bean的时候,会执行这里的getEarlyBeanReference方法,在这个方法中会去执行一些后置处理器的方法。 AbstractAutoProxyCreator会生成一个代理对象,这里就是提前进行了aop代理对象的生成。
在这里会去执行一些后置处理器的postProcessPropertyValues方法, @Autowired注解的AutowiredAnnotationBeanPostProcessor就是在这里生效的 。下面来看看AutowiredAnnotationBeanPostProcessor对属性依赖注入的处理
在执行后置处理器的postProcessAfterInitialization方法时,会去执行AbstractAutoProxyCreator类的postProcessAfterInitialization方法,这里会去根据需要生成当前bean的aop代理对象。