【Spring源码分析系列】bean的加载

前言

以 BeanFactory bf  = new XmlBeanFactory(new ClassPathResource("beans.xml"));为例查看bean的加载过程。

一、首先来看Spring中是如何实现的

 1 @Override
 2     public Object getBean(String name) throws BeansException {
 3         return getBean(name, Object.class);
 4     }
 5 
 6     @Override
 7     public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
 8         try {
 9             if (isSingleton(name)) {
10                 return doGetSingleton(name, requiredType);
11             }
12             else {
13                 return lookup(name, requiredType);
14             }
15         }
16         catch (NameNotFoundException ex) {
17             throw new NoSuchBeanDefinitionException(name, "not found in JNDI environment");
18         }
19         catch (TypeMismatchNamingException ex) {
20             throw new BeanNotOfRequiredTypeException(name, ex.getRequiredType(), ex.getActualType());
21         }
22         catch (NamingException ex) {
23             throw new BeanDefinitionStoreException("JNDI environment", name, "JNDI lookup failed", ex);
24         }
25     }
1   //检查要加载的bean是否是单例    
2   @Override
3     public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
4         return this.shareableResources.contains(name);
5     }
//如果是单例的话从单例的map中获取bean,如果有的话说明已经加载则直接从map中获取,如果没有则将bean放入单例类的map中,单例在Spring的容器中只会被创建一次,后续再获取bean,就直接从单例缓存获取了。当日这里只是尝试加载,首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中场景bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直接使用ObjectFactory.
@SuppressWarnings("unchecked")
    private <T> T doGetSingleton(String name, Class<T> requiredType) throws NamingException {
        synchronized (this.singletonObjects) {
            if (this.singletonObjects.containsKey(name)) {
                Object jndiObject = this.singletonObjects.get(name);
                if (requiredType != null && !requiredType.isInstance(jndiObject)) {
                    throw new TypeMismatchNamingException(
                            convertJndiName(name), requiredType, (jndiObject != null ? jndiObject.getClass() : null));
                }
                return (T) jndiObject;
            }
            T jndiObject = lookup(name, requiredType);
            this.singletonObjects.put(name, jndiObject);
            return jndiObject;
        }
    }
 1 //实例化Bean
 2 /**
 3      * Perform an actual JNDI lookup for the given name via the JndiTemplate.
 4      * <p>If the name doesn't begin with "java:comp/env/", this prefix is added
 5      * if "resourceRef" is set to "true".
 6      * @param jndiName the JNDI name to look up
 7      * @param requiredType the required type of the object
 8      * @return the obtained object
 9      * @throws NamingException if the JNDI lookup failed
10      * @see #setResourceRef
11      */
12     protected <T> T lookup(String jndiName, Class<T> requiredType) throws NamingException {
13         Assert.notNull(jndiName, "'jndiName' must not be null");
14         String convertedName = convertJndiName(jndiName);
15         T jndiObject;
16         try {
17             jndiObject = getJndiTemplate().lookup(convertedName, requiredType);
18         }
19         catch (NamingException ex) {
20             if (!convertedName.equals(jndiName)) {
21                 // Try fallback to originally specified name...
22                 if (logger.isDebugEnabled()) {
23                     logger.debug("Converted JNDI name [" + convertedName +
24                             "] not found - trying original name [" + jndiName + "]. " + ex);
25                 }
26                 jndiObject = getJndiTemplate().lookup(jndiName, requiredType);
27             }
28             else {
29                 throw ex;
30             }
31         }
32         if (logger.isDebugEnabled()) {
33             logger.debug("Located object with JNDI name [" + convertedName + "]");
34         }
35         return jndiObject;
36     }

二、FactoryBean的使用

一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean.在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量的配置信息,配置信息的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.beans.factory.FactoryBean<T>的工厂类接口,可以通过实现该接口定制实例化bean的逻辑。

FactoryBean接口对于Spring框架来说是非常重要的,Spring自身就提供了70多个FactoryBean的实现,他们影藏了一些实例化复杂bean的细节,给上层应用带来了便利。

该接口中的方法

  1 /*
  2  * Copyright 2002-2016 the original author or authors.
  3  *
  4  * Licensed under the Apache License, Version 2.0 (the "License");
  5  * you may not use this file except in compliance with the License.
  6  * You may obtain a copy of the License at
  7  *
  8  *      http://www.apache.org/licenses/LICENSE-2.0
  9  *
 10  * Unless required by applicable law or agreed to in writing, software
 11  * distributed under the License is distributed on an "AS IS" BASIS,
 12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  * See the License for the specific language governing permissions and
 14  * limitations under the License.
 15  */
 16 
 17 package org.springframework.beans.factory;
 18 
 19 /**
 20  * Interface to be implemented by objects used within a {@link BeanFactory} which
 21  * are themselves factories for individual objects. If a bean implements this
 22  * interface, it is used as a factory for an object to expose, not directly as a
 23  * bean instance that will be exposed itself.
 24  *
 25  * <p><b>NB: A bean that implements this interface cannot be used as a normal bean.</b>
 26  * A FactoryBean is defined in a bean style, but the object exposed for bean
 27  * references ({@link #getObject()}) is always the object that it creates.
 28  *
 29  * <p>FactoryBeans can support singletons and prototypes, and can either create
 30  * objects lazily on demand or eagerly on startup. The {@link SmartFactoryBean}
 31  * interface allows for exposing more fine-grained behavioral metadata.
 32  *
 33  * <p>This interface is heavily used within the framework itself, for example for
 34  * the AOP {@link org.springframework.aop.framework.ProxyFactoryBean} or the
 35  * {@link org.springframework.jndi.JndiObjectFactoryBean}. It can be used for
 36  * custom components as well; however, this is only common for infrastructure code.
 37  *
 38  * <p><b>{@code FactoryBean} is a programmatic contract. Implementations are not
 39  * supposed to rely on annotation-driven injection or other reflective facilities.</b>
 40  * {@link #getObjectType()} {@link #getObject()} invocations may arrive early in
 41  * the bootstrap process, even ahead of any post-processor setup. If you need access
 42  * other beans, implement {@link BeanFactoryAware} and obtain them programmatically.
 43  *
 44  * <p>Finally, FactoryBean objects participate in the containing BeanFactory's
 45  * synchronization of bean creation. There is usually no need for internal
 46  * synchronization other than for purposes of lazy initialization within the
 47  * FactoryBean itself (or the like).
 48  *
 49  * @author Rod Johnson
 50  * @author Juergen Hoeller
 51  * @since 08.03.2003
 52  * @see org.springframework.beans.factory.BeanFactory
 53  * @see org.springframework.aop.framework.ProxyFactoryBean
 54  * @see org.springframework.jndi.JndiObjectFactoryBean
 55  */
 56 public interface FactoryBean<T> {
 57 
 58     /**
 59          *返回由FactoryBean创建的bean实例,如果isSingleton返回true则该实例会放到Spring容器中单实例缓存池中
 60      * Return an instance (possibly shared or independent) of the object
 61      * managed by this factory.
 62      * <p>As with a {@link BeanFactory}, this allows support for both the
 63      * Singleton and Prototype design pattern.
 64      * <p>If this FactoryBean is not fully initialized yet at the time of
 65      * the call (for example because it is involved in a circular reference),
 66      * throw a corresponding {@link FactoryBeanNotInitializedException}.
 67      * <p>As of Spring 2.0, FactoryBeans are allowed to return {@code null}
 68      * objects. The factory will consider this as normal value to be used; it
 69      * will not throw a FactoryBeanNotInitializedException in this case anymore.
 70      * FactoryBean implementations are encouraged to throw
 71      * FactoryBeanNotInitializedException themselves now, as appropriate.
 72      * @return an instance of the bean (can be {@code null})
 73      * @throws Exception in case of creation errors
 74      * @see FactoryBeanNotInitializedException
 75      */
 76     T getObject() throws Exception;
 77 
 78     /**
 79          *返回FactoryBean创建的bean类型
 80      * Return the type of object that this FactoryBean creates,
 81      * or {@code null} if not known in advance.
 82      * <p>This allows one to check for specific types of beans without
 83      * instantiating objects, for example on autowiring.
 84      * <p>In the case of implementations that are creating a singleton object,
 85      * this method should try to avoid singleton creation as far as possible;
 86      * it should rather estimate the type in advance.
 87      * For prototypes, returning a meaningful type here is advisable too.
 88      * <p>This method can be called <i>before</i> this FactoryBean has
 89      * been fully initialized. It must not rely on state created during
 90      * initialization; of course, it can still use such state if available.
 91      * <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
 92      * {@code null} here. Therefore it is highly recommended to implement
 93      * this method properly, using the current state of the FactoryBean.
 94      * @return the type of object that this FactoryBean creates,
 95      * or {@code null} if not known at the time of the call
 96      * @see ListableBeanFactory#getBeansOfType
 97      */
 98     Class<?> getObjectType();
 99 
100     /**
101          *返回由FactoryBean创建的bean实例的作用域是singleton还是prototype
102      * Is the object managed by this factory a singleton? That is,
103      * will {@link #getObject()} always return the same object
104      * (a reference that can be cached)?
105      * <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
106      * the object returned from {@code getObject()} might get cached
107      * by the owning BeanFactory. Hence, do not return {@code true}
108      * unless the FactoryBean always exposes the same reference.
109      * <p>The singleton status of the FactoryBean itself will generally
110      * be provided by the owning BeanFactory; usually, it has to be
111      * defined as singleton there.
112      * <p><b>NOTE:</b> This method returning {@code false} does not
113      * necessarily indicate that returned objects are independent instances.
114      * An implementation of the extended {@link SmartFactoryBean} interface
115      * may explicitly indicate independent instances through its
116      * {@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}
117      * implementations which do not implement this extended interface are
118      * simply assumed to always return independent instances if the
119      * {@code isSingleton()} implementation returns {@code false}.
120      * @return whether the exposed object is a singleton
121      * @see #getObject()
122      * @see SmartFactoryBean#isPrototype()
123      */
124     boolean isSingleton();
125 
126 }

当配置文件中<bean>的class配置的实现类是FactoryBean时,通过getbean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。

1 <bean id="car" class="com.slp.factorybean.CarFactoryBean" carInfo="BMW,400,200000"/>

当调用getBean("car")时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回,如果希望获取CarFactoryBean的实例则需要使用getBean(beanName)方法时在beanName前显式的加上&前缀,例如getBean("&car");

三、从缓存中获取单例bean

介绍过FactoryBean的用法之后,就可以了解bean加载的过程了。单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取,当然这里也只是尝试加载,首先尝试从缓存中加载,然后再次尝试从singletonFactorry加载因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则不等bean创建完成就会创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory.

四、从bean的实例中获取对象

在getBean方法中,getObjectForBeanInstance是个使用非常多的方法,,物流是从缓存中获得bean还是根据不同的scope策略加载bean,宗旨我们得到bean的第一步就是用这个方法检测其正确性。也就是检测当前bean是否是FactoryBean类型的bean,如果是那么需要调用该bean对应的FactoryBean实例中的getObject()作为返回值。

无论是从缓存中获取到的bean还是通过不同的scope策略加载的bean都只是最原始的bena状态,并不一定是我们最终想要的bean.

五、循环依赖

循环依赖其实就是循环引用,循环调用时无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误。

Spring容器循环依赖包括构造器循环依赖个setter循环依赖。

1、构造器循环依赖

通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖。

Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean标识符在创建过程中将一直保持在这个池中,因此如果在创建bean的过程中发现自己已经在“当前创建bean池”里时,将抛出BeanCurrentlyInCreationException异常表示循环依赖,而对于创建完毕的bean将从“当前创建bean池”中清除掉。

警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testA' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testB' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testB' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testC' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testC' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testA': Requested bean is currently in creation: Is there an unresolvable circular reference?
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testA' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testB' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testB' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testC' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testC' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testA': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.slp.TestConfig.main(TestConfig.java:24)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testB' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testC' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testC' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testA': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 17 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'testC' defined in class path resource [beans2.xml]: Cannot resolve reference to bean 'testA' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testA': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:634)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:145)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 29 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'testA': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:347)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 41 more

2、setter循环依赖

表示通过setter注入方式构成的循环依赖,对于setter注入造成的依赖是通过Spring容器提前暴露刚完成的构造器注入但未完成其他步骤的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而使得其他bean能引用到该bean.

1)Spring容器创建单例"testA"bean,首先根据无参构造器创建bean,并暴露一个ObjectFactory用于返回一个提前暴露一个创建中的bean,并将testA标识符放到"当前创建bean池",然后进行setter注入"testB";

2)Spring容器创建单例“testB”bean,首先根据无参构造器创建bean,并暴露一个"ObjectFactory"用于返货一个提前暴露一个创建中的bean,并将"testB"标识符放到"当前创建bean池",然后进行setter注入"circle".

3)Spring容器创建单例“testC” bean,首先根据无参构造器创建bean,并暴露一个ObjectFactory用于返回一个提前暴露一个创建中的bean,并将testC标识符放到“当前创建bean池”,然后进行setter注入testA,进行注入testA时由于提前暴露了ObjectFactory工厂,从而使用它返回提前暴露一个创建中的bean.

4)最后在依赖注入testB和testA完成setter注入

3、prototype范围的依赖处理

对于prototype作用域bean,Spring容器无法完成依赖注入,因为Spring容器不进行缓存prototype作用域的bean,因此无法提前暴露一个创建中的bean.

对于singleton作用域bean,可以通过setAllowCircularReferencess(false)来禁止循环引用。

五、创建bean

  1 /**
  2      * Actually create the specified bean. Pre-creation processing has already happened
  3      * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
  4      * <p>Differentiates between default bean instantiation, use of a
  5      * factory method, and autowiring a constructor.
  6      * @param beanName the name of the bean
  7      * @param mbd the merged bean definition for the bean
  8      * @param args explicit arguments to use for constructor or factory method invocation
  9      * @return a new instance of the bean
 10      * @throws BeanCreationException if the bean could not be created
 11      * @see #instantiateBean
 12      * @see #instantiateUsingFactoryMethod
 13      * @see #autowireConstructor
 14      */
 15     protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
 16             throws BeanCreationException {
 17 
 18         // Instantiate the bean.
 19         BeanWrapper instanceWrapper = null;
 20         if (mbd.isSingleton()) {
 21             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 22         }
 23         if (instanceWrapper == null) {
 24                 //根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化
 25             instanceWrapper = createBeanInstance(beanName, mbd, args);
 26         }
 27         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
 28         Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
 29         mbd.resolvedTargetType = beanType;
 30 
 31         // Allow post-processors to modify the merged bean definition.
 32         synchronized (mbd.postProcessingLock) {
 33             if (!mbd.postProcessed) {
 34                 try {
 35     //应用MergedBeanDefinitionPostProcessor                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 36                 }
 37                 catch (Throwable ex) {
 38                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 39                             "Post-processing of merged bean definition failed", ex);
 40                 }
 41                 mbd.postProcessed = true;
 42             }
 43         }
 44 
 45         // Eagerly cache singletons to be able to resolve circular references
 46         // even when triggered by lifecycle interfaces like BeanFactoryAware.
 47               //是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中。检查循环依赖
 48         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
 49                 isSingletonCurrentlyInCreation(beanName));
 50         if (earlySingletonExposure) {
 51             if (logger.isDebugEnabled()) {
 52                 logger.debug("Eagerly caching bean '" + beanName +
 53                         "' to allow for resolving potential circular references");
 54             }
 55 //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
 56             addSingletonFactory(beanName, new ObjectFactory<Object>() {
 57                 @Override
 58                 public Object getObject() throws BeansException {
 59 //对bean再一次依赖引用,注意应用SmartInstantiationAware BeanPostProcessor.
 60 //其中我们熟知的AOP就是在这里将Advice动态植入bean中,若没有则直接返回bean,不做任何处理
 61                     return getEarlyBeanReference(beanName, mbd, bean);
 62                 }
 63             });
 64         }
 65 
 66         // Initialize the bean instance.
 67         Object exposedObject = bean;
 68         try {
 69 //对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,则会递归初始依赖bean
 70             populateBean(beanName, mbd, instanceWrapper);
 71             if (exposedObject != null) {
 72 //调用初始化方法,比如init-method
 73                 exposedObject = initializeBean(beanName, exposedObject, mbd);
 74             }
 75         }
 76         catch (Throwable ex) {
 77             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
 78                 throw (BeanCreationException) ex;
 79             }
 80             else {
 81                 throw new BeanCreationException(
 82                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 83             }
 84         }
 85 
 86         if (earlySingletonExposure) {
 87             Object earlySingletonReference = getSingleton(beanName, false);
 88 //earlySingletonReference 只有在检测到有循环依赖的情况下才会不为空
 89             if (earlySingletonReference != null) {
 90 //如果exposedObject没有在初始化方法中被改变,也就是没有被增强
 91                 if (exposedObject == bean) {
 92                     exposedObject = earlySingletonReference;
 93                 }
 94                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
 95                     String[] dependentBeans = getDependentBeans(beanName);
 96                     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
 97 //检测依赖
 98                     for (String dependentBean : dependentBeans) {
 99                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
100                             actualDependentBeans.add(dependentBean);
101                         }
102                     }
103 //因为bean创建后其所依赖的bean一定是已经创建的,actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在依赖循环
104                     if (!actualDependentBeans.isEmpty()) {
105                         throw new BeanCurrentlyInCreationException(beanName,
106                                 "Bean with name '" + beanName + "' has been injected into other beans [" +
107                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
108                                 "] in its raw version as part of a circular reference, but has eventually been " +
109                                 "wrapped. This means that said other beans do not use the final version of the " +
110                                 "bean. This is often the result of over-eager type matching - consider using " +
111                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
112                     }
113                 }
114             }
115         }
116 
117         // Register bean as disposable.
118         try {
119 //根据scopse注册bean
120             registerDisposableBeanIfNecessary(beanName, bean, mbd);
121         }
122         catch (BeanDefinitionValidationException ex) {
123             throw new BeanCreationException(
124                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
125         }
126 
127         return exposedObject;
128     }

1、如果是单例则需要首先清楚缓存

2、实例化bean,将BeanDefinition转换为BeanWrapper

1)如果存在工厂方法则使用工厂方法进行初始化

 1 /**
 2      * Create a new instance for the specified bean, using an appropriate instantiation strategy:
 3      * factory method, constructor autowiring, or simple instantiation.
 4      * @param beanName the name of the bean
 5      * @param mbd the bean definition for the bean
 6      * @param args explicit arguments to use for constructor or factory method invocation
 7      * @return BeanWrapper for the new instance
 8      * @see #instantiateUsingFactoryMethod
 9      * @see #autowireConstructor
10      * @see #instantiateBean
11      */
12     protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
13         // Make sure bean class is actually resolved at this point.
14                 //解析class
15         Class<?> beanClass = resolveBeanClass(mbd, beanName);
16 
17         if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
18             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
19                     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
20         }
21               //如果工厂方法不为空则使用工厂方法初始化策略
22         if (mbd.getFactoryMethodName() != null)  {
23             return instantiateUsingFactoryMethod(beanName, mbd, args);
24         }
25 
26         // Shortcut when re-creating the same bean...
27         boolean resolved = false;
28         boolean autowireNecessary = false;
29         if (args == null) {
30             synchronized (mbd.constructorArgumentLock) {
31                //一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要先根据参数锁定构造函数或对应的工厂方法
32                 if (mbd.resolvedConstructorOrFactoryMethod != null) {
33                     resolved = true;
34                     autowireNecessary = mbd.constructorArgumentsResolved;
35                 }
36             }
37         }
38               //如果已经解析过则使用解析好的构造函数方法不需要再次锁定
39         if (resolved) {
40             if (autowireNecessary) {
41                            //构造函数自动注入
42                 return autowireConstructor(beanName, mbd, null, null);
43             }
44             else {
45                             //使用默认构造函数构造
46                 return instantiateBean(beanName, mbd);
47             }
48         }
49 
50         // Need to determine the constructor...
51                 //需要根据参数解析构造函数
52         Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
53         if (ctors != null ||
54                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
55                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
56                    //构造函数自动注入
57             return autowireConstructor(beanName, mbd, ctors, args);
58         }
59 
60         // No special handling: simply use no-arg constructor.
61                 //使用默认构造函数构造
62         return instantiateBean(beanName, mbd);
63     }
  • 如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method那么Spring会尝试使用instantiateUsingFactoryMethod(beanName,mbd,args)方法根据RootBeanDefinition中的配置生产bean的实例。
  • 解析构造函数并进行构造函数的实例化,因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。但是判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition中的属性resolveConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中。

2)一个类有多个构造函数,每个构造函数都有不同的参数,所以需要根据参数锁定构造函数并进行初始化

  1 /**
  2      * "autowire constructor" (with constructor arguments by type) behavior.
  3      * Also applied if explicit constructor argument values are specified,
  4      * matching all remaining arguments with beans from the bean factory.
  5      * <p>This corresponds to constructor injection: In this mode, a Spring
  6      * bean factory is able to host components that expect constructor-based
  7      * dependency resolution.
  8      * @param beanName the name of the bean
  9      * @param mbd the merged bean definition for the bean
 10      * @param chosenCtors chosen candidate constructors (or {@code null} if none)
 11      * @param explicitArgs argument values passed in programmatically via the getBean method,
 12      * or {@code null} if none (-> use constructor argument values from bean definition)
 13      * @return a BeanWrapper for the new instance
 14      */
 15     public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
 16             Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
 17 
 18         BeanWrapperImpl bw = new BeanWrapperImpl();
 19         this.beanFactory.initBeanWrapper(bw);
 20 
 21         Constructor<?> constructorToUse = null;
 22         ArgumentsHolder argsHolderToUse = null;
 23         Object[] argsToUse = null;
 24               //explicitArgs通过getBean方法传入
 25               //如果getBean方法调用的时候指定方法参数那么直接使用
 26         if (explicitArgs != null) {
 27             argsToUse = explicitArgs;
 28         }
 29         else {
 30                   //如果在getBean方法时候没有指定则尝试从配置文件中解析
 31             Object[] argsToResolve = null;
 32                      //尝试从缓存中获取
 33             synchronized (mbd.constructorArgumentLock) {
 34                 constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
 35                 if (constructorToUse != null && mbd.constructorArgumentsResolved) {
 36                     // Found a cached constructor...
 37                                            //从缓存中取
 38                     argsToUse = mbd.resolvedConstructorArguments;
 39                     if (argsToUse == null) {
 40                                           //配置的构造函数参数
 41                         argsToResolve = mbd.preparedConstructorArguments;
 42                     }
 43                 }
 44             }
 45                     //如果缓存中存在
 46             if (argsToResolve != null) {
 47                             //解析参数类型,如给定方法的构造函数A(int,int)则通过此方法后就会把配置中的("1","1")转换为(1,1)
 48                            //缓存中的值可能是原始值也可能是最终值
 49                 argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
 50             }
 51         }
 52               //没有被缓存
 53         if (constructorToUse == null) {
 54             // Need to resolve the constructor.
 55             boolean autowiring = (chosenCtors != null ||
 56                     mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
 57             ConstructorArgumentValues resolvedValues = null;
 58 
 59             int minNrOfArgs;
 60             if (explicitArgs != null) {
 61                 minNrOfArgs = explicitArgs.length;
 62             }
 63             else {
 64                        //提取配置文件中的配置的构造函数参数
 65                 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
 66                            //用于承载解析后的构造函数参数的值
 67                 resolvedValues = new ConstructorArgumentValues();
 68                           //能解析到的参数个数
 69                 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
 70             }
 71 
 72             // Take specified constructors, if any.
 73             Constructor<?>[] candidates = chosenCtors;
 74             if (candidates == null) {
 75                 Class<?> beanClass = mbd.getBeanClass();
 76                 try {
 77                     candidates = (mbd.isNonPublicAccessAllowed() ?
 78                             beanClass.getDeclaredConstructors() : beanClass.getConstructors());
 79                 }
 80                 catch (Throwable ex) {
 81                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 82                             "Resolution of declared constructors on bean Class [" + beanClass.getName() +
 83                             "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
 84                 }
 85             }
 86                      //排序给定的构造函数,public构造函数优先参数数量降序、非public构造函数参数数量降序
 87             AutowireUtils.sortConstructors(candidates);
 88             int minTypeDiffWeight = Integer.MAX_VALUE;
 89             Set<Constructor<?>> ambiguousConstructors = null;
 90             LinkedList<UnsatisfiedDependencyException> causes = null;
 91 
 92             for (Constructor<?> candidate : candidates) {
 93                 Class<?>[] paramTypes = candidate.getParameterTypes();
 94 
 95                 if (constructorToUse != null && argsToUse.length > paramTypes.length) {
 96                          //如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,因为已经按照参数个数降序排列
 97                     // Already found greedy constructor that can be satisfied ->
 98                     // do not look any further, there are only less greedy constructors left.
 99                     break;
100                 }
101                 if (paramTypes.length < minNrOfArgs) {
102                                  //参数个数不相等
103                     continue;
104                 }
105 
106                 ArgumentsHolder argsHolder;
107                 if (resolvedValues != null) {
108                                  //有参数则根据值构造对应参数类型的参数
109                     try {
110                         String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
111                         if (paramNames == null) {
112                                    //获取参数名称探索器
113                             ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
114                             if (pnd != null) {
115                                                           //获取指定构造函数的参数名称
116                                 paramNames = pnd.getParameterNames(candidate);
117                             }
118                         }
119                                       //根据名称和数据类型创建参数持有者
120                         argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
121                                 getUserDeclaredConstructor(candidate), autowiring);
122                     }
123                     catch (UnsatisfiedDependencyException ex) {
124                         if (this.beanFactory.logger.isTraceEnabled()) {
125                             this.beanFactory.logger.trace(
126                                     "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
127                         }
128                         // Swallow and try next constructor.
129                         if (causes == null) {
130                             causes = new LinkedList<UnsatisfiedDependencyException>();
131                         }
132                         causes.add(ex);
133                         continue;
134                     }
135                 }
136                 else {
137                     // Explicit arguments given -> arguments length must match exactly.
138                     if (paramTypes.length != explicitArgs.length) {
139                         continue;
140                     }
141                                        //构造函数没有参数的情况
142                     argsHolder = new ArgumentsHolder(explicitArgs);
143                 }
144                                //探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
145                 int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
146                         argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
147                 // Choose this constructor if it represents the closest match.
148                             //如果它代表着当前最接近的匹配则选择作为构造函数
149                 if (typeDiffWeight < minTypeDiffWeight) {
150                     constructorToUse = candidate;
151                     argsHolderToUse = argsHolder;
152                     argsToUse = argsHolder.arguments;
153                     minTypeDiffWeight = typeDiffWeight;
154                     ambiguousConstructors = null;
155                 }
156                 else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
157                     if (ambiguousConstructors == null) {
158                         ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
159                         ambiguousConstructors.add(constructorToUse);
160                     }
161                     ambiguousConstructors.add(candidate);
162                 }
163             }
164 
165             if (constructorToUse == null) {
166                 if (causes != null) {
167                     UnsatisfiedDependencyException ex = causes.removeLast();
168                     for (Exception cause : causes) {
169                         this.beanFactory.onSuppressedException(cause);
170                     }
171                     throw ex;
172                 }
173                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
174                         "Could not resolve matching constructor " +
175                         "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
176             }
177             else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
178                 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
179                         "Ambiguous constructor matches found in bean '" + beanName + "' " +
180                         "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
181                         ambiguousConstructors);
182             }
183 
184             if (explicitArgs == null) {
185                           //将解析的构造函数加入缓存
186                 argsHolderToUse.storeCache(mbd, constructorToUse);
187             }
188         }
189 
190         try {
191             Object beanInstance;
192 
193             if (System.getSecurityManager() != null) {
194                 final Constructor<?> ctorToUse = constructorToUse;
195                 final Object[] argumentsToUse = argsToUse;
196                 beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
197                     @Override
198                     public Object run() {
199                         return beanFactory.getInstantiationStrategy().instantiate(
200                                 mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
201                     }
202                 }, beanFactory.getAccessControlContext());
203             }
204             else {
205                 beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
206                         mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
207             }
208                          //将构建的实例加入BeanWrapper中
209             bw.setBeanInstance(beanInstance);
210             return bw;
211         }
212         catch (Throwable ex) {
213             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
214                     "Bean instantiation via constructor failed", ex);
215         }
216     }

3)如果既不存在工厂方法也不存在带有参数的构造函数,则使用默认的构造函数进行bean的实例化

 1 /**
 2      * Instantiate the given bean using its default constructor.
 3      * @param beanName the name of the bean
 4      * @param mbd the bean definition for the bean
 5      * @return BeanWrapper for the new instance
 6          * 不带参数的构造函数的实例化过程
 7      */
 8     protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
 9         try {
10             Object beanInstance;
11             final BeanFactory parent = this;
12             if (System.getSecurityManager() != null) {
13                 beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
14                     @Override
15                     public Object run() {
16                         return getInstantiationStrategy().instantiate(mbd, beanName, parent);
17                     }
18                 }, getAccessControlContext());
19             }
20             else {
21                 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
22             }
23             BeanWrapper bw = new BeanWrapperImpl(beanInstance);
24             initBeanWrapper(bw);
25             return bw;
26         }
27         catch (Throwable ex) {
28             throw new BeanCreationException(
29                     mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
30         }
31     }
 1 //实例化策略
 2 @Override
 3     public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
 4         // Don't override the class with CGLIB if no overrides.
 5                 //如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理,因为可以在创建代理的同时将动态方法织入类中
 6                //但是如果没有需要动态改变的方法,为了方便直接反射就可以了
 7         if (bd.getMethodOverrides().isEmpty()) {
 8             Constructor<?> constructorToUse;
 9             synchronized (bd.constructorArgumentLock) {
10                 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
11                 if (constructorToUse == null) {
12                     final Class<?> clazz = bd.getBeanClass();
13                     if (clazz.isInterface()) {
14                         throw new BeanInstantiationException(clazz, "Specified class is an interface");
15                     }
16                     try {
17                         if (System.getSecurityManager() != null) {
18                             constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
19                                 @Override
20                                 public Constructor<?> run() throws Exception {
21                                     return clazz.getDeclaredConstructor((Class[]) null);
22                                 }
23                             });
24                         }
25                         else {
26                             constructorToUse =    clazz.getDeclaredConstructor((Class[]) null);
27                         }
28                         bd.resolvedConstructorOrFactoryMethod = constructorToUse;
29                     }
30                     catch (Throwable ex) {
31                         throw new BeanInstantiationException(clazz, "No default constructor found", ex);
32                     }
33                 }
34             }
35             return BeanUtils.instantiateClass(constructorToUse);
36         }
37         else {
38             // Must generate CGLIB subclass.
39             return instantiateWithMethodInjection(bd, beanName, owner);
40         }
41     }

3)MergedBeanDefinitionPostProcessor的应用

bean合并后的处理,Autowired注解正是通过此方法实现注入类型的预解析

4)依赖处理

在Spring中会有循环依赖额情况,例如,当A中含有B的属性,而B中又含有A的属性时就会构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例,这样就解决了循环依赖的问题。

5)属性填充,将所有属性填充至bean的实例中

 1 /**
 2      * Populate the bean instance in the given BeanWrapper with the property values
 3      * from the bean definition.
 4      * @param beanName the name of the bean
 5      * @param mbd the bean definition for the bean
 6      * @param bw BeanWrapper with bean instance
 7      */
 8     protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
 9         PropertyValues pvs = mbd.getPropertyValues();
10 
11         if (bw == null) {
12             if (!pvs.isEmpty()) {
13                 throw new BeanCreationException(
14                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
15             }
16             else {
17                 // Skip property population phase for null instance.                    
18                                //没有可填充的属性
19                 return;
20             }
21         }
22 
23         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
24         // state of the bean before properties are set. This can be used, for example,
25         // to support styles of field injection.               
26               //给InstantiationAwareBeanPostProcessors最后一次机会在属性设置前来改变bean.
27                //如:可以用来支撑属性注入的类型
28         boolean continueWithPropertyPopulation = true;
29 
30         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
31             for (BeanPostProcessor bp : getBeanPostProcessors()) {
32                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
33                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
34                        //返回值为是否继续填充bean
35                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
36                         continueWithPropertyPopulation = false;
37                         break;
38                     }
39                 }
40             }
41         }
42                  //如果后处理器发出停止填充命令则终止后续的执行
43         if (!continueWithPropertyPopulation) {
44             return;
45         }
46 
47         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
48                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
49             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
50 
51             // Add property values based on autowire by name if applicable.
52                         //根据名称自动注入
53             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
54                 autowireByName(beanName, mbd, bw, newPvs);
55             }
56 
57             // Add property values based on autowire by type if applicable.
58                        //根据类型自动注入
59             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
60                 autowireByType(beanName, mbd, bw, newPvs);
61             }
62 
63             pvs = newPvs;
64         }
65                //后处理器已经初始化
66         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
67               //需要依赖检查
68         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
69 
70         if (hasInstAwareBpps || needsDepCheck) {
71             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
72             if (hasInstAwareBpps) {
73                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
74                     if (bp instanceof InstantiationAwareBeanPostProcessor) {
75                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
76                      //对所有需要依赖检查的属性进行后处理
77                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
78                         if (pvs == null) {
79                             return;
80                         }
81                     }
82                 }
83             }
84             if (needsDepCheck) {
85                     //依赖检查,对应depends-on属性
86                 checkDependencies(beanName, mbd, filteredPds, pvs);
87             }
88         }
89                      //将属性应用到bean中
90         applyPropertyValues(beanName, mbd, bw, pvs);
91     }
  • InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantitation函数的应用,此函数可以控制程序是否继续进行属性填充
  • 根据注入类型(byName/byType)提取依赖的bean,并统一存入PropertyValues中
    • autoWireByName
    •  1 /**
       2      * Fill in any missing property values with references to
       3      * other beans in this factory if autowire is set to "byName".
       4      * @param beanName the name of the bean we're wiring up.
       5      * Useful for debugging messages; not used functionally.
       6      * @param mbd bean definition to update through autowiring
       7      * @param bw BeanWrapper from which we can obtain information about the bean
       8      * @param pvs the PropertyValues to register wired objects with
       9      */
      10     protected void autowireByName(
      11             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
      12                  //寻找bw中需要依赖注入的属性
      13         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
      14         for (String propertyName : propertyNames) {
      15             if (containsBean(propertyName)) {
      16                         //递归初始化相关的bean
      17                 Object bean = getBean(propertyName);
      18                 pvs.add(propertyName, bean);
      19                               //注册依赖
      20                 registerDependentBean(propertyName, beanName);
      21                 if (logger.isDebugEnabled()) {
      22                     logger.debug("Added autowiring by name from bean name '" + beanName +
      23                             "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
      24                 }
      25             }
      26             else {
      27                 if (logger.isTraceEnabled()) {
      28                     logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
      29                             "' by name: no matching bean found");
      30                 }
      31             }
      32         }
      33     }
    • autowireByType
    •  1 /**
       2      * Abstract method defining "autowire by type" (bean properties by type) behavior.
       3      * <p>This is like PicoContainer default, in which there must be exactly one bean
       4      * of the property type in the bean factory. This makes bean factories simple to
       5      * configure for small namespaces, but doesn't work as well as standard Spring
       6      * behavior for bigger applications.
       7      * @param beanName the name of the bean to autowire by type
       8      * @param mbd the merged bean definition to update through autowiring
       9      * @param bw BeanWrapper from which we can obtain information about the bean
      10      * @param pvs the PropertyValues to register wired objects with
      11      */
      12     protected void autowireByType(
      13             String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
      14 
      15         TypeConverter converter = getCustomTypeConverter();
      16         if (converter == null) {
      17             converter = bw;
      18         }
      19 
      20         Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
      21                //寻找bw中需要依赖注入的属性
      22         String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
      23         for (String propertyName : propertyNames) {
      24             try {
      25                 PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
      26                 // Don't try autowiring by type for type Object: never makes sense,
      27                 // even if it technically is a unsatisfied, non-simple property.
      28                 if (Object.class != pd.getPropertyType()) {
      29                                           //探测指定属性的set方法
      30                     MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
      31                     // Do not allow eager init for type matching in case of a prioritized post-processor.
      32                     boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
      33                     DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
      34                               //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowireBeanNames中,当属性存在多个封装bean时
      35                     Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
      36                     if (autowiredArgument != null) {
      37                         pvs.add(propertyName, autowiredArgument);
      38                     }
      39                     for (String autowiredBeanName : autowiredBeanNames) {
      40                     //注册依赖    registerDependentBean(autowiredBeanName, beanName);
      41                         if (logger.isDebugEnabled()) {
      42                             logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
      43                                     propertyName + "' to bean named '" + autowiredBeanName + "'");
      44                         }
      45                     }
      46                     autowiredBeanNames.clear();
      47                 }
      48             }
      49             catch (BeansException ex) {
      50                 throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      51             }
      52         }
      53     }
    • 寻找类型匹配的逻辑实现封装resolveDependency
    •  1 @Override
       2     public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
       3             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
       4 
       5         descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
       6         if (javaUtilOptionalClass == descriptor.getDependencyType()) {
       7             return new OptionalDependencyFactory().createOptionalDependency(descriptor, requestingBeanName);
       8         }
       9         else if (ObjectFactory.class == descriptor.getDependencyType() ||
      10                 ObjectProvider.class == descriptor.getDependencyType()) {
      11             return new DependencyObjectProvider(descriptor, requestingBeanName);
      12         }
      13         else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
      14             return new Jsr330ProviderFactory().createDependencyProvider(descriptor, requestingBeanName);
      15         }
      16         else {
      17             Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
      18                     descriptor, requestingBeanName);
      19             if (result == null) {
      20                 result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      21             }
      22             return result;
      23         }
      24     }
      25 
      26     public Object doResolveDependency(DependencyDescriptor descriptor, String beanName,
      27             Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
      28 
      29         InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
      30         try {
      31             Object shortcut = descriptor.resolveShortcut(this);
      32             if (shortcut != null) {
      33                 return shortcut;
      34             }
      35 
      36             Class<?> type = descriptor.getDependencyType();
      37             Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      38             if (value != null) {
      39                 if (value instanceof String) {
      40                     String strVal = resolveEmbeddedValue((String) value);
      41                     BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
      42                     value = evaluateBeanDefinitionString(strVal, bd);
      43                 }
      44                 TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
      45                 return (descriptor.getField() != null ?
      46                         converter.convertIfNecessary(value, type, descriptor.getField()) :
      47                         converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
      48             }
      49 
      50             Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      51             if (multipleBeans != null) {
      52                 return multipleBeans;
      53             }
      54 
      55             Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      56             if (matchingBeans.isEmpty()) {
      57                 if (isRequired(descriptor)) {
      58                     raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
      59                 }
      60                 return null;
      61             }
      62 
      63             String autowiredBeanName;
      64             Object instanceCandidate;
      65 
      66             if (matchingBeans.size() > 1) {
      67                 autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
      68                 if (autowiredBeanName == null) {
      69                     if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
      70                         return descriptor.resolveNotUnique(type, matchingBeans);
      71                     }
      72                     else {
      73                         // In case of an optional Collection/Map, silently ignore a non-unique case:
      74                         // possibly it was meant to be an empty collection of multiple regular beans
      75                         // (before 4.3 in particular when we didn't even look for collection beans).
      76                         return null;
      77                     }
      78                 }
      79                 instanceCandidate = matchingBeans.get(autowiredBeanName);
      80             }
      81             else {
      82                 // We have exactly one match.
      83                 Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
      84                 autowiredBeanName = entry.getKey();
      85                 instanceCandidate = entry.getValue();
      86             }
      87 
      88             if (autowiredBeanNames != null) {
      89                 autowiredBeanNames.add(autowiredBeanName);
      90             }
      91             return (instanceCandidate instanceof Class ?
      92                     descriptor.resolveCandidate(autowiredBeanName, type, this) : instanceCandidate);
      93         }
      94         finally {
      95             ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
      96         }
      97     }
  • 应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理,典型应用是RequiredAnnotationBeanPostProcessor类中对属性的验证
  • 将所有PropertyValues中的属性填充至BeanWrapper中

6)循环依赖检查

Spring中循环依赖只对单例有效,而对于prototype的bean,Spring没有好的解决办法,唯一要做的就是抛出异常,在这个步骤里会检测已经加载的bean是否已经出现了依赖循环,并判断是否需要抛出异常。

7)注册DisposableBean

如果配置了destory-method这里需要注册以便于在销毁时调用

8)完成创建并返回

原文地址:https://www.cnblogs.com/dream-to-pku/p/7598057.html