IOC之Bean的初始化(实例化与依赖注入)
文章目录
-
-
-
-
-
-
-
-
-
-
前情概要
回顾之前的内容IOC初始化之准备工作(定位、加载、注册) ,说到在
ApplicationContext
初始化时,会先去根据资源路径去定位、加载并且注册Bean信息到BeanFactory
中,但此过程并未实例化,在结尾也说了,在调用BeanFactory的getBean方法时Bean才会真正实例化。那么在ApplicationContext
中是什么时候去初始化Bean的呢?回顾一下refresh方法:1234567891011121314151617
@Overridepublic void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Tell the subclass to refresh the internal bean factory. //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从 //子类的refreshBeanFactory()方法启动 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //略... // Instantiate all remaining (non-lazy-init) singletons. //初始化所有剩余的单例Bean finishBeanFactoryInitialization(beanFactory); //略...}
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {// Tell the subclass to refresh the internal bean factory. //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从 //子类的refreshBeanFactory()方法启动 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //略... // Instantiate all remaining (non-lazy-init) singletons. //初始化所有剩余的单例Bean finishBeanFactoryInitialization(beanFactory); //略...
}
由refresh方法可知,
ApplicationContext
将在方法接近末尾的时候去初始化Bean,但不是初始化所有Bean,而是作用域为singleton单例的且配置lazy-init=false才会进行初始化Bean的操作。123456789
//对配置了lazy-init属性的Bean进行预实例化处理protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //略... // Instantiate all remaining (non-lazy-init) singletons. //对配置了lazy-init属性的单态模式Bean进行预实例化处理 beanFactory.preInstantiateSingletons();}
//对配置了lazy-init属性的Bean进行预实例化处理
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {//略... // Instantiate all remaining (non-lazy-init) singletons. //对配置了lazy-init属性的单态模式Bean进行预实例化处理 beanFactory.preInstantiateSingletons();
}
注意这里初始化方法还是委托给了我们上一篇文章说的BeanFactory去做,而不是
ApplicationContext
,对于很多操作Bean的场景大部分都是由DefaultListableBeanFactory
去做。12345678910111213141516171819202122232425262728293031323334353637383940414243444546
//对配置lazy-init属性单态Bean的预实例化@Overridepublic void preInstantiateSingletons() throws BeansException { // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. ListString beanNames = new ArrayList(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... //遍历所有的beanNames for (String beanName : beanNames) { //获取指定名称的Bean定义 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //如果指定名称的bean是创建容器的Bean if (isFactoryBean(beanName)) { //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号 //时,获取的是产生容器对象本身,而不是容器产生的Bean. //调用getBean方法,触发容器对Bean实例化和依赖注入过程 final FactoryBean? factory = (FactoryBean?) getBean(FACTORY_BEAN_PREFIX + beanName); //标识是否需要预实例化 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { //一个匿名内部类 isEagerInit = AccessController.doPrivileged((PrivilegedActionBoolean) () - ((SmartFactoryBean?) factory).isEagerInit(), getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean?) factory).isEagerInit()); } if (isEagerInit) { //调用getBean方法,触发容器对Bean实例化和依赖注入过程 getBean(beanName); } } else { getBean(beanName); } } } //略...}
//对配置lazy-init属性单态Bean的预实例化
@Override
public void preInstantiateSingletons() throws BeansException {// Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. ListString beanNames = new ArrayList(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... //遍历所有的beanNames for (String beanName : beanNames) { //获取指定名称的Bean定义 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //Bean不是抽象的,是单态模式的,且lazy-init属性配置为false if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //如果指定名称的bean是创建容器的Bean if (isFactoryBean(beanName)) { //FACTORY_BEAN_PREFIX=”&”,当Bean名称前面加”&”符号 //时,获取的是产生容器对象本身,而不是容器产生的Bean. //调用getBean方法,触发容器对Bean实例化和依赖注入过程 final FactoryBean? factory = (FactoryBean?) getBean(FACTORY_BEAN_PREFIX + beanName); //标识是否需要预实例化 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { //一个匿名内部类 isEagerInit = AccessController.doPrivileged((PrivilegedActionBoolean) () - ((SmartFactoryBean?) factory).isEagerInit(), getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean?) factory).isEagerInit()); } if (isEagerInit) { //调用getBean方法,触发容器对Bean实例化和依赖注入过程 getBean(beanName); } } else { getBean(beanName); } } } //略...
}
可以看到,这里会遍历所有的Bean,如果是单例且lazy-init=false才会进行初始化,而真正初始化的工作将从getBean方法 中展开。
初始化Bean
在BeanFactory继承体系结构中,可以看到
AbstractBeanFactory
这个抽象类实现了BeanFactory接口,自然在这个抽象类中会实现getBean方法:123456
//获取IOC容器中指定名称的Bean@Overridepublic Object getBean(String name) throws BeansException { //doGetBean才是真正向IoC容器获取被管理Bean的过程 return doGetBean(name, null, null, false);}
//获取IOC容器中指定名称的Bean
@Override
public Object getBean(String name) throws BeansException {
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, null, null, false);
}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
//真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方protected T T doGetBean(final String name, @Nullable final ClassT requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖 //如果指定的是别名,将别名转换为规范的Bean名称 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //先从缓存中取是否已经有被创建过的单态类型的Bean //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建 Object sharedInstance = getSingleton(beanName); //IOC容器创建单例模式Bean实例对象 if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { //如果指定名称的Bean在容器中已有单例模式的Bean被创建 //直接返回已经创建的Bean 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的实例对象,主要是完成FactoryBean的相关处理 //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是 //创建创建对象的工厂Bean,两者之间有区别 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //缓存没有正在创建的单例模式Bean //缓存中已经有已经创建的原型模式Bean //但是由于循环引用的问题导致实例化对象失败 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否 //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器 //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找 BeanFactory parentBeanFactory = getParentBeanFactory(); //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found - check parent. //解析指定Bean名称的原始名称 String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. //委派父级容器根据指定名称和显式的参数查找 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args - delegate to standard getBean method. //委派父级容器根据指定名称和类型查找 return parentBeanFactory.getBean(nameToLookup, requiredType); } } //创建的Bean是否需要进行类型验证,一般不需要 if (!typeCheckOnly) { //向容器标记指定的Bean已经被创建 markBeanAsCreated(beanName); } try { //根据指定Bean名称获取其父级的Bean定义 //主要解决Bean继承时子类合并父类公共属性问题 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //获取当前Bean所有依赖Bean的名称 String[] dependsOn = mbd.getDependsOn(); //如果当前Bean有依赖Bean 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 + "'"); } //递归调用getBean方法,获取当前Bean的依赖Bean registerDependentBean(dep, beanName); //把被依赖Bean注册给当前依赖的Bean getBean(dep); } } // Create bean instance. //创建单例模式Bean的实例对象 if (mbd.isSingleton()) { //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 sharedInstance = getSingleton(beanName, () - { try { //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. //显式地从容器单例模式Bean缓存中清除实例对象 destroySingleton(beanName); throw ex; } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //IOC容器创建原型模式Bean实例对象 else if (mbd.isPrototype()) { // It's a prototype - create a new instance. //原型模式(Prototype)是每次都会创建一个新的对象 Object prototypeInstance = null; try { //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象 beforePrototypeCreation(beanName); //创建指定Bean对象实例 prototypeInstance = createBean(beanName, mbd, args); } finally { //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建 afterPrototypeCreation(beanName); } //获取给定Bean的实例对象 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中 //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中 //比较常用,如:request、session、application等生命周期 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); //Bean定义资源中没有配置生命周期范围,则Bean定义不合法 if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { //这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例 Object scopedInstance = scope.get(beanName, () - { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. //对创建的Bean实例对象进行类型检查 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean;}
//真正实现向IOC容器获取Bean的功能,也是触发依赖注入功能的地方
protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {//根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖 //如果指定的是别名,将别名转换为规范的Bean名称 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //先从缓存中取是否已经有被创建过的单态类型的Bean //对于单例模式的Bean整个IOC容器中只创建一次,不需要重复创建 Object sharedInstance = getSingleton(beanName); //IOC容器创建单例模式Bean实例对象 if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { //如果指定名称的Bean在容器中已有单例模式的Bean被创建 //直接返回已经创建的Bean 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的实例对象,主要是完成FactoryBean的相关处理 //注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是 //创建创建对象的工厂Bean,两者之间有区别 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. //缓存没有正在创建的单例模式Bean //缓存中已经有已经创建的原型模式Bean //但是由于循环引用的问题导致实例化对象失败 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //对IOC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否 //能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器 //的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找 BeanFactory parentBeanFactory = getParentBeanFactory(); //当前容器的父级容器存在,且当前容器中不存在指定名称的Bean if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found - check parent. //解析指定Bean名称的原始名称 String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. //委派父级容器根据指定名称和显式的参数查找 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args - delegate to standard getBean method. //委派父级容器根据指定名称和类型查找 return parentBeanFactory.getBean(nameToLookup, requiredType); } } //创建的Bean是否需要进行类型验证,一般不需要 if (!typeCheckOnly) { //向容器标记指定的Bean已经被创建 markBeanAsCreated(beanName); } try { //根据指定Bean名称获取其父级的Bean定义 //主要解决Bean继承时子类合并父类公共属性问题 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //获取当前Bean所有依赖Bean的名称 String[] dependsOn = mbd.getDependsOn(); //如果当前Bean有依赖Bean 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 + "'"); } //递归调用getBean方法,获取当前Bean的依赖Bean registerDependentBean(dep, beanName); //把被依赖Bean注册给当前依赖的Bean getBean(dep); } } // Create bean instance. //创建单例模式Bean的实例对象 if (mbd.isSingleton()) { //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 sharedInstance = getSingleton(beanName, () - { try { //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. //显式地从容器单例模式Bean缓存中清除实例对象 destroySingleton(beanName); throw ex; } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //IOC容器创建原型模式Bean实例对象 else if (mbd.isPrototype()) { // It's a prototype - create a new instance. //原型模式(Prototype)是每次都会创建一个新的对象 Object prototypeInstance = null; try { //回调beforePrototypeCreation方法,默认的功能是注册当前创建的原型对象 beforePrototypeCreation(beanName); //创建指定Bean对象实例 prototypeInstance = createBean(beanName, mbd, args); } finally { //回调afterPrototypeCreation方法,默认的功能告诉IOC容器指定Bean的原型对象不再创建 afterPrototypeCreation(beanName); } //获取给定Bean的实例对象 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } //要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中 //配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中 //比较常用,如:request、session、application等生命周期 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); //Bean定义资源中没有配置生命周期范围,则Bean定义不合法 if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { //这里又使用了一个匿名内部类,获取一个指定生命周期范围的实例 Object scopedInstance = scope.get(beanName, () - { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. //对创建的Bean实例对象进行类型检查 if (requiredType != null && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean;
}
在doGetBean方法中,其实做了很多事,这里一一解释:
- 首先调用 getSingleton(beanName); 方法,先尝试获取一个单例实例,这个方法解决了循环依赖的问题,下面我会详细的说明。
- 如果尝试获取的实例不存在当前IOC容器,如果父容器不为空会去父容器中获取Bean。
- 经过以上步骤都没有获取到Bean实例的话,先寻找所有依赖的Bean,对依赖的Bean循环调用getBean()方法(依赖Bean有可能为单例,此时如果是单例Bean的话这样做的目的第一是先将此Bean初始化,第二是会将其缓存下来,等之后依赖注入会用到)
- 如果是单例Bean:调用getSingleton方法,其第二个参数
ObjectFactory
是一个功能接口,里面有一个模板提供方法,getObject,调用方法返回实例,所以在外面调用getSingleton方法时使用匿名类方式将子类createBean方法赋给ObjectFactory
对象的getObject方法,便于在getSingleton方法中可以调用。这里是一个面向函数式编程思想 。这里多一层getSingleton方法是为了解决循环依赖问题 ,下面会详细解释。 - 如果是原型Bean:直接调用子类createBean方法,因为其不需要经过一些循环依赖步骤,换言之,如果有原型Bean循环依赖了,是不能解决的,会抛出异常。
- 如果是其他scope的Bean:会设置其scope,然后同样是调用createBean去创建。
到这里我们应该要明白了,真正去创建Bean的方法是createBean:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
//创建Bean实例对象@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. //判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载 Class? resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //略... try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try { //创建Bean的入口 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } //略...}
//创建Bean实例对象
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//判断需要创建的Bean是否可以实例化,即是否可以通过当前的类加载器加载
Class? resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
//略...
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//如果Bean配置了初始化前和初始化后的处理器,则试图返回一个需要创建Bean的代理对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建Bean的入口
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
//略...
}
这里也分步骤进行解读:
- 首先会先判断此Bean是否可以实例化。
- 然后此时会调用resolveBeforeInstantiation方法,这是一个通知回调方法,会将此时的Bean的Class与BeanName传入容器中实现了
InstantiationAwareBeanPostProcessor
接口的方法postProcessBeforeInstantiation。举个例子AbstractAutoProxyCreator
这个类实现了BeanPostProcessor
这个接口来完成AOP代理,但它同时也实现了InstantiationAwareBeanPostProcessor
这个接口,这个接口的方法调用时间即为上述Bean实例化与依赖注入之前(doCreateBean 才真正进行Bean实例化与依赖注入)。如果关于BeanPostProcessor
的知识不懂的话,可以看看下一章我会讲到Spring的自定义扩展方式,然后下下章讲到AOP的时候也会详细讲解AbstractAutoProxyCreator
实现InstantiationAwareBeanPostProcessor
接口的真正作用,这里读者只要记住,InstantiationAwareBeanPostProcessor
的调用时机是在Bean实例化以前。 - 如果此时
InstantiationAwareBeanPostProcessor
的回调方法没有获取到Bean(自定义扩展的内容,说明没有进行自定义扩展),那么进入真正创建Bean的方法doCreateBean。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
//真正创建Bean的方法protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. //封装被创建的Bean对象 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); //获取实例化对象的类型 Class? beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. //调用PostProcessor后置处理器 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. //向容器中缓存单例模式的Bean对象,以防循环引用 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用 addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. //Bean对象的初始化,依赖注入在此触发 //这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean Object exposedObject = bean; try { //将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象 populateBean(beanName, mbd, instanceWrapper); //初始化Bean对象 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { //抛异常..略... } } if (earlySingletonExposure) { //获取指定名称的已注册的单例模式Bean对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //根据名称获取的已注册的Bean和正在实例化的Bean是同一个 if (exposedObject == bean) { //当前实例化的Bean初始化完成 exposedObject = earlySingletonReference; } //当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); SetString actualDependentBeans = new LinkedHashSet(dependentBeans.length); //获取当前Bean所依赖的其他Bean for (String dependentBean : dependentBeans) { //对依赖Bean进行类型检查 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } //略... } } } // Register bean as disposable. //注册完成依赖注入的Bean try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;}
//真正创建Bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
//获取实例化对象的类型
Class? beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
//调用PostProcessor后置处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//向容器中缓存单例模式的Bean对象,以防循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
//抛异常..略...
}
}
if (earlySingletonExposure) {
//获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean) {
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
}
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
SetString actualDependentBeans = new LinkedHashSet(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans) {
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//略...
}
}
}
// Register bean as disposable.
//注册完成依赖注入的Bean
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
- 创建完成的Bean实例,其实又被Spring封装了一层,最终封装Bean为
BeanWrapper
,此封装类存放Bean实例对象、Bean的Class类型等。createBeanInstance(beanName, mbd, args) 方法会实例化Bean,并且封装成BeanWrapper
返回。注意此时仅仅只是调用构造器实例化Bean而已。 - 在实例化Bean之后,如果该Bean是单例且允许循环依赖(可在配置中配置此属性),在此为了解决循环引用,提前将对象引用暴露出来,下面会提到循环引用的解决方法。
- 到这里Bean已经实例化好了,接下来调用populateBean(beanName, mbd, instanceWrapper) 方法进行依赖注入。
- 此时的Bean已是实例化且依赖注入好的Bean,接着会调用initializeBean(beanName, exposedObject, mbd) 方法,该方法是一个回调通知方法,在扩展Spring中会详细解释,这里只要记住,在这个时机Spring提供出了一个回调方法可供扩展。
- 调用 registerDisposableBeanIfNecessary(beanName, bean, mbd); 方法注册此Bean。
解决循环依赖的问题
什么是循环依赖?
假设aBean中需要依赖bBean,而bBean中也需要依赖aBean,这时初始化aBean时,需要进行依赖注入,所以需要初始化bBean,而在bBean初始化时又需要依赖注入,此时需要一个aBean,这就造成了一个死锁,aBean在等待bBean初始化好,才能完成aBean的初始化,而bBean又在等待aBean初始化好,才能完成bBean的初始化,那么在Spring中是如何解决这种循环依赖问题的呢?
Spring中如何解决循环依赖
让我们回顾一下时序,我们先是调用了getBean方法,接着调用doGetBean方法真正去获取Bean,不知读者是否还记得,此时会先去调用getSingleton(beanName) 方法,尝试获取一个单例实例:
123456789101112131415161718192021222324252627
@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) { //尝试先从singletonObjects获取实例 Object singletonObject = this.singletonObjects获取实例.get(beanName); //如果singletonObjects没有存放此Bean的实例的话,获取早期暴露的实例 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //先尝试从早期暴露缓存earlySingletonObjects中获取 singletonObject = this.earlySingletonObjects.get(beanName); //早期暴露的缓存没有的话,去早期暴露的Map中获取 if (singletonObject == null && allowEarlyReference) { //singletonFactories此Map即为早期暴露的Map ObjectFactory? singletonFactory = this.singletonFactories.get(beanName); //如果可以获取到早期暴露的对象的话 if (singletonFactory != null) { //从此singletonFactory中获取Bean实例 singletonObject = singletonFactory.getObject(); //存放在早期暴露的缓存中,下次取只需要从earlySingletonObjects拿即可 this.earlySingletonObjects.put(beanName, singletonObject); //由于已经存放在缓存中,singletonFactories继续存放没有意义,移除 this.singletonFactories.remove(beanName); } } } } return singletonObject;}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//尝试先从singletonObjects获取实例
Object singletonObject = this.singletonObjects获取实例.get(beanName);
//如果singletonObjects没有存放此Bean的实例的话,获取早期暴露的实例
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//先尝试从早期暴露缓存earlySingletonObjects中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//早期暴露的缓存没有的话,去早期暴露的Map中获取
if (singletonObject == null && allowEarlyReference) {
//singletonFactories此Map即为早期暴露的Map
ObjectFactory? singletonFactory = this.singletonFactories.get(beanName);
//如果可以获取到早期暴露的对象的话
if (singletonFactory != null) {
//从此singletonFactory中获取Bean实例
singletonObject = singletonFactory.getObject();
//存放在早期暴露的缓存中,下次取只需要从earlySingletonObjects拿即可
this.earlySingletonObjects.put(beanName, singletonObject);
//由于已经存放在缓存中,singletonFactories继续存放没有意义,移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
此时读者需要记住几个Map,关注接下来的方法它们的put时机和put的value到底是什么:
- singletonObjects:存放单例Bean的一个Map。
- earlySingletonObjects :早期暴露的缓存,在获取早期暴露对象之后会进行缓存。
- singletonFactories :关键解决了循环依赖问题的一个Map对象,方式是过早暴露Bean引用。需要关注的点是它的value是一个
ObjectFactory
对象,此时依然是面向函数式编程 ,此接口只是一个功能暴露接口,也就是最终调用singletonFactory.getObject(); 的方法为关键,该方法获取早期Bean实例。
接着回忆一下,在尝试调用getSingleton方法未获得对象时,会判断是否为单例,如果Bean为单例则会调用getSingleton(String beanName, ObjectFactory? singletonFactory) 方法,注意此时的方法与上面的参数不一样,重载方法:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
public Object getSingleton(String beanName, ObjectFactory? singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); //此过程需要进行同步处理 synchronized (this.singletonObjects) { //依然先尝试从singletonObjects中获取 Object singletonObject = this.singletonObjects.get(beanName); //获取不到的话 if (singletonObject == null) { //如果此时单例Bean已经是在创建了,由于是单例的Bean,所以需要抛出异常 if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } //此时就是上述提到的创建Bean的标识,在此标记此Bean已经正在创建 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet(); } try { //面向函数编程,调用功能接口中的方法获取单例Bean,getObject方法的实现 //在调用getSingleton之前就已经使用匿名类的方式传入 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime - // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } //此时移除Bean创建的标识,表示此Bean不在创建时间了,已经创建完成 afterSingletonCreation(beanName); } if (newSingleton) { //此时会将创建好了的Bean存入单例Map中 addSingleton(beanName, singletonObject); } } return singletonObject; }}
public Object getSingleton(String beanName, ObjectFactory? singletonFactory) {
Assert.notNull(beanName, “Bean name must not be null”);
//此过程需要进行同步处理
synchronized (this.singletonObjects) {
//依然先尝试从singletonObjects中获取
Object singletonObject = this.singletonObjects.get(beanName);
//获取不到的话
if (singletonObject == null) {
//如果此时单例Bean已经是在创建了,由于是单例的Bean,所以需要抛出异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
“Singleton bean creation not allowed while singletons of this factory are in destruction “ +
“(Do not request a bean from a BeanFactory in a destroy method implementation!)”);
}
if (logger.isDebugEnabled()) {
logger.debug(“Creating shared instance of singleton bean ‘“ + beanName + “‘“);
}
//此时就是上述提到的创建Bean的标识,在此标记此Bean已经正在创建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//面向函数编程,调用功能接口中的方法获取单例Bean,getObject方法的实现
//在调用getSingleton之前就已经使用匿名类的方式传入
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime -
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//此时移除Bean创建的标识,表示此Bean不在创建时间了,已经创建完成
afterSingletonCreation(beanName);
}
if (newSingleton) {
//此时会将创建好了的Bean存入单例Map中
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
123456789101112
protected void addSingleton(String beanName, Object singletonObject) { //需要同步处理 synchronized (this.singletonObjects) { //加入singletonObjects以供后续getBean时直接获取实例 this.singletonObjects.put(beanName, singletonObject); //将早期暴露的实例移除,就算不移除这里也没有用了,因为根本不会有进入此Map的时机 this.singletonFactories.remove(beanName); //这里就更不用说了,不会有进入此Map的时机 this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); }}
protected void addSingleton(String beanName, Object singletonObject) {
//需要同步处理
synchronized (this.singletonObjects) {
//加入singletonObjects以供后续getBean时直接获取实例
this.singletonObjects.put(beanName, singletonObject);
//将早期暴露的实例移除,就算不移除这里也没有用了,因为根本不会有进入此Map的时机
this.singletonFactories.remove(beanName);
//这里就更不用说了,不会有进入此Map的时机
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
由于此时已经将完整的Bean(实例化以及依赖注入完成)创建出来了,所以直接放入singletonObjects这个Map中,以供后续getBean时就可以直接取出。如果你还记得上面我让你记住的那几个Map的话,此时你应该可以有一个承上启下的感觉,singletonObjects是在初始化Bean完成时才会put实例 。
此时我们回到创建单例Bean中:
123456789101112131415161718192021
// Create bean instance.//创建单例模式Bean的实例对象if (mbd.isSingleton()) { //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 sharedInstance = getSingleton(beanName, () - { try { //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. //显式地从容器单例模式Bean缓存中清除实例对象 destroySingleton(beanName); throw ex; } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
// Create bean instance.
//创建单例模式Bean的实例对象
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () - {
try {
//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
//显式地从容器单例模式Bean缓存中清除实例对象
destroySingleton(beanName);
throw ex;
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
这里可以看得出来,此时将子类实现的createBean方法传入getSingleton中以供后续getObject调用,也就是说,真正创建Bean的方法是createBean(在上面说初始化的时候也有提到,所以这里只是提一下经过了哪些方法,不贴代码详细描述),而createBean中判断了一下此Bean是否可以实例化,接着调用真正干事情的doCreateBean方法去初始化Bean,此时会先调用构造器实例化此Bean,注意此时仅仅是实例化一个Bean对象出来,Bean实例还未依赖注入,此时会调用这样一段代码:
1234567891011
//向容器中缓存单例模式的Bean对象,以防循环引用boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } //这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用 addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}
//向容器中缓存单例模式的Bean对象,以防循环引用
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug(“Eagerly caching bean ‘“ + beanName +
“‘ to allow for resolving potential circular references”);
}
//这里是一个匿名内部类,为了防止循环引用,尽早持有对象的引用
addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));
}
上面也有说过,这里会判断是否为单例,且允许循环依赖,才会进入addSingletonFactory方法:
12345678910111213
protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); //同步处理 synchronized (this.singletonObjects) { //如果singletonObjects不存在该Bean才进行早期暴露 if (!this.singletonObjects.containsKey(beanName)) { //会put一个功能接口对象到singletonFactories这个Map中 this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }}
protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {
Assert.notNull(singletonFactory, “Singleton factory must not be null”);
//同步处理
synchronized (this.singletonObjects) {
//如果singletonObjects不存在该Bean才进行早期暴露
if (!this.singletonObjects.containsKey(beanName)) {
//会put一个功能接口对象到singletonFactories这个Map中
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
此方法我称为一个早期暴露实例的方法,注意此时这里可以通过getEarlyBeanReference方法获得此时Bean的引用(Bean仅仅是实例化),然后将该方法传给
ObjectFactory
这个功能接口的getObject方法,此时只需要将
ObjectFactory
这个具有获取早期Bean引用的方法的对象put进singletonFactories这个Map中,读到这里,聪明的读者应该已经知道了Spring到底是如何解决循环依赖问题的了。
循环依赖总结
心中需要有一个时序图,你将会看的更清晰:
getBean - doGetBean - 先去singletonObjects这个Map中查看是否已经有Bean实例,如果没有 - 此Bean为单例的情况下,查看singletonFactories此Map是否有早期暴露的单例Bean引用 - 如果有证明此时这个单例Bean在其他地方已经在创建了,此时只需要返回此引用作为Bean实例即可。
- singletonObjects时机:会在完整创建完一个单例Bean时,存放起来,容器即为singletonObjects这个Map,并且会移除早期暴露 singletonFactories 这个Map中关于该Bean的引用。
- singletonFactories时机:在单例Bean情况下,在仅仅是实例化还未依赖注入此Bean时提前将Bean引用早期就存放在singletonFactories这个Map中,所以在doGetBean 尝试获取Bean实例时即可拿到一个Bean引用。
此时就来回顾一下上述的循环依赖问题:
当创建
aBean
时,先去看看singletonObjects是否已经有实例,显然是没有,然后就会实例化此Bean,在这之后,依赖注入之前,将
aBean
的引用存放在singletonFactories这个Map中,然后进行依赖注入,此时发现
aBean
依赖
bBean
,所以需要去初始化
bBean
,依然是先看看singletonObjects是否有
bBean
,显然也没有,然后就实例化
bBean
,在
bBean
依赖注入时,发现此
Bean
依赖
aBean
,所以又去初始化
aBean
了,然后
aBean
又去singletonObjects看是否存在实例,显然此时还是没有的,然后去singletonFactories这个Map查找的时候,发现存在一个Bean引用,所以获取该引用作为
aBean
,将此引用注入到
bBean
完成
bBean
依赖注入的过程,
bBean
初始化结束,然后回到
aBean
依赖注入,初始化
bBean
成功,将
bBean
注入到
aBean
,然后
aBean
初始化也成功,没有循环依赖问题。
为什么早期暴露一个引用就可以解决循环依赖问题呢?
还是看这个例子,在
bBean
中注入的
aBean
依赖仅仅是一个
aBean
实例化之后还未依赖注入(不完整的
aBean
)引用,但当
aBean
也初始化好了,
bBean
中的
aBean
(此时是完整的aBean)不也初始化好了吗?因为引用指向的对象都是同一个地址,这样
bBean
就能提前初始化好,只有
bBean
初始化好了
aBean
才能初始化好,所以解决了循环依赖的问题。
但此时有一个问题,在上面介绍的所有的过程都是针对于单例Bean的,如果不是单例Bean根本都不会进行上述操作,如果是原型Bean循环依赖另一个原型Bean怎么办呢?目前我所知道的这个应该是解决不了的,在初始化的过程中就会报循环依赖的异常,所以要保证Bean为单例,才可以循环依赖。
FactoryBean
FactoryBean是Spring定义的一个特殊的Bean,先来看看它定义了什么方法:
1234567891011121314151617
//工厂Bean,用于产生其他对象public interface FactoryBeanT { //获取容器管理的对象实例 @Nullable T getObject() throws Exception; //获取Bean工厂创建的对象的类型 @Nullable Class? getObjectType(); //Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例 //对象,每次请求都返回同一个实例对象 default boolean isSingleton() { return true; }}
//工厂Bean,用于产生其他对象
public interface FactoryBean {
//获取容器管理的对象实例
@Nullable
T getObject() throws Exception;
//获取Bean工厂创建的对象的类型
@Nullable
Class? getObjectType();
//Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例
//对象,每次请求都返回同一个实例对象
default boolean isSingleton() {
return true;
}
}
如果此Bean是FactoryBean,就必须实现FactoryBean接口。通过该接口可以看出FactoryBean的一些特性:
- getObeject:定义了一个获取Bean对象的方法。
- getObjectType:定义了一个获取Bean的Class对象的方法。
- isSingleton:判断此Factory生成的Bean是否为单例Bean,默认为true。
FactoryBean是什么
它是一个特殊的Bean,从名字就可以看出来,它是由Bean结尾的,意味着是一个Bean,但此Bean是工厂类型的Bean,什么意思呢?普通Bean只是IOC容器管理的真正代码中使用的对象,但工厂Bean不是我们要使用的对象,它负责生产真正的Bean,它是一个工厂,但它也是由工厂(BeanFactory)生产出来的,也就是说,FactroyBean是用来生产Bean而生的。
FactoryBean在IOC容器哪里用到
在
BeanFactory
接口中,定义了一个静态变量:
123
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,//如果需要得到工厂本身,需要转义String FACTORY_BEAN_PREFIX = "&";
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = “&”;
这个用处是用来区分要获取的是FactoryBean本身还是FactoryBean生产出来的Bean。假设有一个FactoryBean,BeanName=“demo”,你调用getBean方法希望获取到它的本身,你需要加一个符号:getBean(“&demo”),此时你get到的对象会是FactoryBean本身,如果不加此符号,会获取此FactoryBean的方法getObject生产出来的Bean作为返回值。没听懂?看看下面就懂了。
回顾以上初始化Bean的过程,我们回到getBean之后的doGetBean这个一开始的起点方法中:
123456789101112131415161718192021
// Create bean instance.//创建单例模式Bean的实例对象if (mbd.isSingleton()) { //这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象 sharedInstance = getSingleton(beanName, () - { try { //创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义 return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. //显式地从容器单例模式Bean缓存中清除实例对象 destroySingleton(beanName); throw ex; } }); //获取给定Bean的实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}
// Create bean instance.
//创建单例模式Bean的实例对象
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () - {
try {
//创建一个指定Bean实例对象,如果有父级继承,则合并子类和父类的定义
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
//显式地从容器单例模式Bean缓存中清除实例对象
destroySingleton(beanName);
throw ex;
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
这里举一个创建单例Bean过程的一段代码。我们上面介绍了createBean的流程,此时返回一个Bean是已经是实例化好了并且依赖注入完成,各种回调方法完成之后的一个Bean实例
sharedInstance
,但是它没有真正的返回出去,而是又执行了一个方法getObjectForBeanInstance:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. //容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean, //也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象, //如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象 //如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址), //且Bean实例也不是创建Bean实例对象的工厂Bean if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. //如果Bean实例不是工厂Bean,或者指定名称是容器的解引用, //调用者向获取对容器的引用,则直接返回当前的Bean实例 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } //处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean //使用工厂Bean创建一个Bean的实例对象 Object object = null; if (mbd == null) { //从Bean工厂缓存中获取给定名称的Bean实例对象 object = getCachedObjectForFactoryBean(beanName); } //让Bean工厂生产给定名称的Bean对象实例 if (object == null) { // Return bean instance from factory. FactoryBean? factory = (FactoryBean?) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. //如果从Bean工厂生产的Bean是单态模式的,则缓存 if (mbd == null && containsBeanDefinition(beanName)) { //从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性 mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); //调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法, //实现工厂Bean生产Bean对象实例的过程 object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object;}
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//容器已经得到了Bean实例对象,这个实例对象可能是一个普通的Bean,
//也可能是一个工厂Bean,如果是一个工厂Bean,则使用它创建一个Bean实例对象,
//如果调用本身就想获得一个容器的引用,则指定返回这个工厂Bean实例对象
//如果指定的名称是容器的解引用(dereference,即是对象本身而非内存地址),
//且Bean实例也不是创建Bean实例对象的工厂Bean
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
//如果Bean实例不是工厂Bean,或者指定名称是容器的解引用,
//调用者向获取对容器的引用,则直接返回当前的Bean实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//处理指定名称不是容器的解引用,或者根据名称获取的Bean实例对象是一个工厂Bean
//使用工厂Bean创建一个Bean的实例对象
Object object = null;
if (mbd == null) {
//从Bean工厂缓存中获取给定名称的Bean实例对象
object = getCachedObjectForFactoryBean(beanName);
}
//让Bean工厂生产给定名称的Bean对象实例
if (object == null) {
// Return bean instance from factory.
FactoryBean? factory = (FactoryBean?) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
//如果从Bean工厂生产的Bean是单态模式的,则缓存
if (mbd == null && containsBeanDefinition(beanName)) {
//从容器中获取指定名称的Bean定义,如果继承基类,则合并基类相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,
//实现工厂Bean生产Bean对象实例的过程
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
也就是说,每一个Bean在初始化完成时,都会进入这个方法,这个方法会判断该Bean是否是FactoryBean,如果是的话,我们需要get的并不是这个FactoryBean,而是FactoryBean生产出来的Bean。
- 先是判断get的名称是否为 “&” 符号开头,如果是的话就是指获取FactoryBean本身即可,但此Bean又没有实现FactoryBean,也就是说在不是FactoryBean的Bean上获取本身(”&”)将会抛出异常。
- 再是判断该Bean如果不是FactoryBean,说明是普通Bean,直接返回本身即可,亦或是以”&”开头的,上面也说了,以“&”开头的话获取的是本身,所以也是直接返回本身即可。
- 如果程序运行到了这里,我们可以知道,此Bean是一个FactoryBean,且并不是获取本身,而是获取FactoryBean生产出来的Bean,此时会先去FactoryBean缓存中获取是否有已经创建好了的Bean实例。
- 缓存如果有返回缓存即可,缓存没有就调用getObjectFromFactoryBean方法,从FactoryBean中生产Bean
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
//Bean工厂生产Bean实例对象protected Object getObjectFromFactoryBean(FactoryBean? factory, String beanName, boolean shouldPostProcess) { //Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象 if (factory.isSingleton() && containsSingleton(beanName)) { //多线程同步,以防止数据不一致 synchronized (getSingletonMutex()) { //直接从Bean工厂缓存中获取指定名称的Bean实例对象 Object object = this.factoryBeanObjectCache.get(beanName); //Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象 if (object == null) { //调用Bean工厂的getObject方法生产指定Bean的实例对象 object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } } //将生产的实例对象添加到Bean工厂缓存中 this.factoryBeanObjectCache.put(beanName, object); } } return object; } } //调用Bean工厂的getObject方法生产指定Bean的实例对象 else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; }}
//Bean工厂生产Bean实例对象
protected Object getObjectFromFactoryBean(FactoryBean? factory, String beanName, boolean shouldPostProcess) {
//Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象
if (factory.isSingleton() && containsSingleton(beanName)) {
//多线程同步,以防止数据不一致
synchronized (getSingletonMutex()) {
//直接从Bean工厂缓存中获取指定名称的Bean实例对象
Object object = this.factoryBeanObjectCache.get(beanName);
//Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象
if (object == null) {
//调用Bean工厂的getObject方法生产指定Bean的实例对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
“Post-processing of FactoryBean’s singleton object failed”, ex);
}
}
//将生产的实例对象添加到Bean工厂缓存中
this.factoryBeanObjectCache.put(beanName, object);
}
}
return object;
}
}
//调用Bean工厂的getObject方法生产指定Bean的实例对象
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, “Post-processing of FactoryBean’s object failed”, ex);
}
}
return object;
}
}
- 首先判断FactoryBean生产的Bean是否为单例的,判断方法在FactoryBean接口中就已经定义此方法,并且要在熟悉的singletonObjects这个存放单例Bean的Map中存在此Bean,就可以判断生产的Bean为单例,所以需要缓存它,这个过程需要同步控制,接下来就调用doGetObjectFromFactoryBean方法去获取真正的Bean,并将其放入缓存中**factoryBeanObjectCache.put(beanName, object)**,以便下一次获取。然后返回真正生产出来的Bean。
- 此时如果走到这里,说明生产出来的Bean为非单例的,所以不需要缓存,只需要简单的调用doGetObjectFromFactoryBean方法去获取真正的Bean返回即可
以上两种可能性都调用了同一个方法doGetObjectFromFactoryBean:
123456789101112131415
//调用Bean工厂的getObject方法生产指定Bean的实例对象private Object doGetObjectFromFactoryBean(final FactoryBean? factory, final String beanName) throws BeanCreationException { Object object; //安全验证,略... //调用BeanFactory接口实现类的创建对象方法 object = factory.getObject(); //略... return object;}
//调用Bean工厂的getObject方法生产指定Bean的实例对象
private Object doGetObjectFromFactoryBean(final FactoryBean? factory, final String beanName)
throws BeanCreationException {
Object object;
//安全验证,略...
//调用BeanFactory接口实现类的创建对象方法
object = factory.getObject();
//略...
return object;
}
为了凸显出主线,我删减了一些支线代码,在这里可以看出来,最终调用的是FactoryBean的getObject方法,正是FactoryBean接口定义的这个方法,此方法为生产Bean的方法。
FactoryBean例子
为了加深理解,我举一个生产环境都会用到的一个FactoryBean来演示到底FactoryBean有什么用。
这里我拿MyBatis与Spring整合包下的一个类
MapperFactoryBean
作为例子讲解一下:
123456789101112131415
/** * {@inheritDoc} */@Overridepublic T getObject() throws Exception { return getSqlSession().getMapper(this.mapperInterface);} /** * {@inheritDoc} */@Overridepublic boolean isSingleton() { return true;}
/**
- {@inheritDoc}
*/
@Override
public T getObject() throws Exception {
return getSqlSession().getMapper(this.mapperInterface);
}
/**
- {@inheritDoc}
*/
@Override
public boolean isSingleton() {
return true;
}
这里贴两个主要方法(需要有一点MyBatis的基础),我在分析MyBatis那篇文章中有提到,我们定义的那些Mapper接口,其实是SqlSession调用getMapper方法创建出来的,从以上getObject中可以看出,
MapperFactoryBean
是一个专门生产Mapper的一个FactoryBean,从isSingleton方法中可以看出,获取的Mapper都为单例。我们回忆一下在使用SSM的时候,如果是一个一个Mapper去配置成Bean放在IOC容器中,需要这样写:
1234
bean id="demoMapper" class="org.mybatis.Spring.mapper.MapperFactoryBean" property name="mapperInterface" value="com.demo.DemoMapper"/property property name="sqlSessionFactory" ref="sqlSessionFactory"/property/bean
bean id=”demoMapper” class=”org.mybatis.Spring.mapper.MapperFactoryBean”
property name=”mapperInterface” value=”com.demo.DemoMapper”/property
property name=”sqlSessionFactory” ref=”sqlSessionFactory”/property
/bean
请注意,此Bean的class类型就是我们上面介绍的
MapperFactoryBean
,其中有属性mapperInterface ,根据此属性去使用getObject方法获取真正的Mapper对象,就算你直接配置一个Mapper扫描路径,它的底层也是将扫描到的每一个mapper接口类型作为
MapperFactoryBean
,以一个FactoryBean的形式存放在IOC容器中,当getBean的时候其实是调用
MapperFactoryBean
这个FactoryBean的getObject方法:
12
@Autowiredprivate DemoMapper demoMapper
@Autowired
private DemoMapper demoMapper
也就是说,你这样使用一个Mapper的时候,Spring容器其实是先获取
MapperFactoryBean
,然后调用所有Bean都会调用的方法getObjectForBeanInstance去进行判断,发现此Bean为一个FactoryBean,调用此Bean的getObject方法,也就是委派其中的SqlSession去getMapper,从而获取真正的Mapper。
总结
到此就结束了初始化Bean的全过程,我们可以总结出来几件事:
- 在Spring中有一个特殊的单例模式,称为注册式单例,往Map中put那些Bean实例达到单例的效果(过程进行同步处理,解决并发问题)。
- 在初始化IOC容器时就会初始化Bean( 单例且lazy-init = false ),并将这些Bean存放在(
BeanFactory
的)Map
中,这可以节省时间,一些单例Bean在启动时就已经创建好,使用时只需获取Map中实例即可。 - 与上一个类似的,如果Bean是除了单例之外的scope,在getBean时同样会走doCrateBean去创建实例,但区别在于不会对其进行缓存,也就是说,除单例之外的scope,可以达到每次getBean都是不同实例的Bean的效果。
- 循环依赖问题只在单例Bean 上被解决,原型Bean之间的循环依赖会抛出异常。
- 在初始化Bean时多次出现回调通知方法,这个特性展现了Spring框架的易扩展性,这是非常强大的设计,将在下一章中对其进行讲解,AOP的实现也依赖于此。
- Factory是一个特殊的Bean ,主要用途是用来生产Bean的,请注意IOC容器中singletonObjects这个Map将会存放所有初始化好的单例Bean(包括那些单例的FactoryBean),而factoryBeanObjectCache存放的则是那些FactoryBean生产出来的Bean,也就是说,IOC容器不仅会存放FactoryBean在容器中,还会存放FactoryBean生产的Bean在容器中,双重缓存加快获取Bean的效率。这里读者要理清两者的关系。