前言
以 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)完成创建并返回