spring中的bean对象和java对象是有些许差别的,spring中的bean包含了java对象,并且是基于java对象在spring中做了一些列的加工,所以说spring中的bean比java对象更加丰富。在spring中bean的实例化有2个时机:
- spring ioc容器初始化的时候,需要预实例化的单例bean。
- 初次调用getBean方法的时候,会触发bean的实例化。
注:spring中的单例bean并不是说容器中这个类的bean实例只能有一个,他和单例模式是有区别的。在spring容器中,单例bean是指类型相同并且同名的实例在同一个spring容器中只允许有一个bean实例。
下面从spring ioc容器初始化的时候,预实例化的bean为线索来追溯bean的实例化和依赖注入过程,这个过程涵盖了getBean方法。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// ...
try {
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
}
catch (BeansException ex) {
// ...
}
}
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// ...
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
public void preInstantiateSingletons() throws BeansException {
//这里根据注册的所有BeanDefinition信息来遍历预实例化所有的bean信息
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//预实例化的条件:非抽象、单例和非懒加载的bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
在spring ioc容器初始化的时候,触发了所有预实例化的bean的加载,这里必须是非抽象、单例和非懒加载的bean才符合条件进行预实例化。具体bean的实例化是在getBean方法中。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
//从缓存中获取bean实例,对于实例化了的bean对象,直接从容器缓存中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// ...
return (T) bean;
}
这里通过getSingleton先从缓存中获取bean实例。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从spring容器一级缓存中获取bean实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果一级缓存中没有,并且bean实例是在创建中(循环依赖)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//从二级缓存中获取,为解决bean的循环依赖添加了二级缓存
singletonObject = this.earlySingletonObjects.get(beanName);
//如果二级缓存中为空,则从三级缓存中获取bean实例
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
//如果三级缓存不为空的时候,这里会去从三级缓存中获取bean实例,这里的bean有可能是已经完成的aop的代理对象,在解决循环依赖的时候会添加上,提前进行aop操作
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
从缓存中获取很好理解,分别从spring容器的一级缓存singletonObjects、二级缓存earlySingletonObjects和三级缓存singletonFactories中获取bean实例。在初次获取bean的时候,这里的缓存肯定为空的,但是对于存在循环依赖的bean,这里的一级或二级缓存就不是空的。在有循环依赖的bean中,这里一级缓存会存在不为空的情况,这个时候通过singletonFactory.getObject的时候,返回的可能是一个bean实例,也有可能是一个提前进行aop的代理对象(正常情况下aop是发生在bean初始化的时候完成的),对于有循环依赖并且需要进行aop的bean,在这里会进行提前aop代理对象的生成。
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// ...
}
else {
//这里把bean添加到集合中,标记为正在创建中
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//当前bean依赖的bean提前先进行实例化,这里和属性的依赖注入不是一个东西
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory
当缓存中没有找到bean实例的时候:
- 先把bean添加到alreadyCreated集合中,标记当前bean正在创建中(为循环依赖做前置判断准备),
- 对于当前bean存在依赖dependsOn的bean,提前在当前bean前进行实例化(这里的dependsOn依赖的bean和属性依赖注入不是一个东西,两者是有区别的)。
- 在BeanDefinition中定义的当前bean是单例的时候,通过getSingleton方法去获取bean实例,这里是通过回调createBean去获取的bean实例。
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
try {
//这里回调的是前面添加的ObjectFactory
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
//获取的是新创建的bean实例,添加到spring容器的一级缓存singletonObjects中
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
通过singletonFactory.getObject回调前面的createBean方法获取bean实例,然后对于是新创建的bean实例添加到spring容器中的一级缓存singletonObjects中。下面从createBean中看bean是如何实例化的。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// ...
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
//这里完成bean的创建过程,这里创建的是一个java对象,并把它包装到instanceWrapper中
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//对于单例并且是正在创建中的bean,为解决循环依赖,添加一个ObjectFactory到三级缓存singletonFactories中,为后续创建bean实例做准备
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//添加一个ObjectFactory到三级缓存中,这里可能会去生成一个aop代理对象
addSingletonFactory(beanName, new ObjectFactory
在这里可以看到整个bean实例化的全貌,也可以看出bean在spring中的生命周期:
- createBeanInstance创建一个bean对象,这个对象是一个干净的java对象
- earlySingletonExposure对于单例正在创建的bean,为解决循环依赖,添加一个ObjectFactory到spring容器的三级缓存中,在后面解决循环依赖的时候用到。
- populateBean设置bean的属性,也就是在这里完成bean的依赖注入,递归地进行bean的实例化。
- initializeBean初始化bean,执行bean的初始化方法,以及相应的后置处理器。
创建bean实例的方法createBeanInstance看看bean的具体创建的方式:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//实例化bean
return instantiateBean(beanName, mbd);
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
// ...
//实例化bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
//这里是根据BeanDefinition中方法是否有重写或增强来判断是用反射还是cglib来进行对象的创建
if (bd.getMethodOverrides().isEmpty()) {
// ...
//根据反射创建bean
return BeanUtils.instantiateClass(constructorToUse);
}
else {
//使用cglib创建bean
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
可以看到在spring中是通过SimpleInstantiationStrategy类来进行bean对象的创建,有java反射和cglib两种方式进行bean的创建,判断依据是,在BeanDefinition中有动态代理或增强的时候会用cglib去创建bean对象。
earlySingletonExposure解决循环依赖
根据bean是单例,并且当前bean是在创建中的时候,会去添加一个ObjectFactory到spring容器的三级缓存singletonFactories中。这里会有可能提前进行aop代理对象的生成。
//对于单例并且是正在创建中的bean,为解决循环依赖,添加一个ObjectFactory到三级缓存singletonFactories中,为后续创建bean实例做准备
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
//添加一个ObjectFactory到三级缓存中,这里可能会去生成一个aop代理对象
addSingletonFactory(beanName, new ObjectFactory
这里把一个ObjectFactory添加到spring容器的三级缓存中去,在前面通过缓存获取bean的时候,会执行这里的getEarlyBeanReference方法,在这个方法中会去执行一些后置处理器的方法。AbstractAutoProxyCreator会生成一个代理对象,这里就是提前进行了aop代理对象的生成。
populateBean设置bean的属性,进行属性的依赖注入
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// ...
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//这里去执行一些后置处理器,譬如@Autowired就是在这里产生作用的
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
applyPropertyValues(beanName, mbd, bw, pvs);
}
在这里会去执行一些后置处理器的postProcessPropertyValues方法,@Autowired注解的AutowiredAnnotationBeanPostProcessor就是在这里生效的。下面来看看AutowiredAnnotationBeanPostProcessor对属性依赖注入的处理
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取所有被@Autowired注解修饰的属性
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//完成属性的依赖注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
initializeBean完成bean的初始化操作
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
- invokeAwareMethods执行一些实现了Aware接口的方法,譬如:设置BeanName、classLoader和BeanFactory给当前bean
- 执行后置处理器的postProcessBeforeInitialization方法
- 执行bean的初始化方法,如果是实现了InitializeBean接口就调用afterPropertiesSet方法,否则就调用自定义的初始化方法。
- 执行后置处理器的postProcessAfterInitialization方法
在执行后置处理器的postProcessAfterInitialization方法时会生成aop代理对象。
在执行后置处理器的postProcessAfterInitialization方法时,会去执行AbstractAutoProxyCreator类的postProcessAfterInitialization方法,这里会去根据需要生成当前bean的aop代理对象。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
spring bean的生命周期:
- 根据jdk反射或cglib生成Bean的java对象。
- 调用populateBean设置bean的属性,这里会进行属性的依赖注入,会去生成依赖的所有bean的实例。
- 执行BeanPostProcessor后置处理器的postProcessBeforeInitialization方法
- 执行bean的初始化方法,可以是实现了InitializingBean接口的afterPropertiesSet,也可以是自定义的初始化方法。
- 执行BeanPostProcessor后置处理器的postProcessAfterInitialization方法,这里会根据需要使用AbstractAutoProxyCreator来生成aop代理对象。