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的效率。这里读者要理清两者的关系。