前提:
一、已經在工程中定義了Spring
配置文件beans.xml
二、寫好了一個測試類HelloWorld,裏面有方法getMessage()
用於輸出"hello world"
。
三、在beans.xml
中配置了一個類HelloWorld
php
示例代碼:html
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); HelloWorld obj = (HelloWorld)context.getBean("HelloWorld"); obj.getMessage();
運行上面代碼,會在控制檯打印出hello world字符。java
注:分析基於spring-framework-4.3.8.RELEASEreact
代碼new ClassPathXmlApplicationContext("beans.xml");
使用了構造函數以下:spring
/** * Create a new ClassPathXmlApplicationContext, loading the definitions * from the given XML file and automatically refreshing the context. * @param configLocation resource location * @throws BeansException if context creation failed */ public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null); } /** * Create a new ClassPathXmlApplicationContext with the given parent, * loading the definitions from the given XML files. * @param configLocations array of resource locations * @param refresh whether to automatically refresh the context, * loading all bean definitions and creating all singletons. * Alternatively, call refresh manually after further configuring the context. * @param parent the parent context * @throws BeansException if context creation failed * @see #refresh() */ public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
上面構造方法調用了org.springframework.context.support.AbstractApplicationContext#refresh
緩存
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //這裏是實例化全部非懶加載的實例 finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
下面是調用構造器時,Spring初始化的主要過程。(refresh)
app
下面是refresh
中的finishBeanFactoryInitialization(beanFactory);
方法的主要過程。(AbstractApplicationContext.finishBeanFactoryInitialization()
)
下面是實例化Bean的過程:jvm
(在新標籤打開查看大圖)ide
下面是加載Bean定義:AbstractXmlApplicationContext.loadBeanDefinitions()
在refresh方法中的obtainFreshBeanFactory的bean定義階段。
調用關係以下:
函數
加載Bean定義過程以下:
因爲未設置HelloWorld類懶加載(lazy-init=true)(默認是non-lazy-load),所以該類是在初始化ClassPathXmlApplicationContext ,即實例化。(參考:spring容器的懶加載lazy-init設置)
在調用getBean方法時,直接從緩存中拿到已經實例化的bean,詳細實現見下面源碼分析。
此外,bean實例化有優先級之分,緣由是實現了BeanFactoryPostProcessor的接口在refresh方法執行invokeBeanFactoryPostProcessors(beanFactory);時就會實例化bean。
由於任何實現了BeanFactoryPostProcessor接口的bean首先要作的事就是先把本身實例化好。
一、調用的獲取bean
的方法是org.springframework.context.support.AbstractApplicationContext#getBean(java.lang.Class<T>)
,源碼以下:
@Override public Object getBean(String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); }
二、上面調用了org.springframework.context.support.AbstractApplicationContext#getBeanFactory
方法
@Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
該方法是個抽象方法,有兩個實現類
//GenericApplicationContext private final DefaultListableBeanFactory beanFactory; /** * Return the single internal BeanFactory held by this context * (as ConfigurableListableBeanFactory). */ @Override public final ConfigurableListableBeanFactory getBeanFactory() { return this.beanFactory; } //AbstractRefreshableApplicationContext /** Bean factory for this context */ private DefaultListableBeanFactory beanFactory; @Override public final ConfigurableListableBeanFactory getBeanFactory() { synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - " + "call 'refresh' before accessing beans via the ApplicationContext"); } return this.beanFactory; } }
最終都是獲得DefaultListableBeanFactory
,所以調用的是org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>)
方法,該方法又調用本類中的org.springframework.beans.factory.support.DefaultListableBeanFactory#getBean(java.lang.Class<T>, java.lang.Object...)
方法。
@Override public <T> T getBean(Class<T> requiredType) throws BeansException { return getBean(requiredType, (Object[]) null); } @Override public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException { NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args); if (namedBean != null) { return namedBean.getBeanInstance(); } BeanFactory parent = getParentBeanFactory(); if (parent != null) { return parent.getBean(requiredType, args); } throw new NoSuchBeanDefinitionException(requiredType); }
三、接着來看DefaultListableBeanFactory
中的resolveNamedBean
方法。
該方法從xml解析註冊到Spring容器中的bean中查找bean的聲名,看是否存在該名字的bean。
而後進行實例化,並返回。
@SuppressWarnings("unchecked") private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException { Assert.notNull(requiredType, "Required type must not be null"); String[] candidateNames = getBeanNamesForType(requiredType);//查找候選的bean名稱 if (candidateNames.length > 1) { //若是有重名的須要進一步處理 List<String> autowireCandidates = new ArrayList<String>(candidateNames.length); for (String beanName : candidateNames) { if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) { autowireCandidates.add(beanName); } } if (!autowireCandidates.isEmpty()) { candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]); } } if (candidateNames.length == 1) {//若是隻有一個,直接進行實例化 String beanName = candidateNames[0]; return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args)); } else if (candidateNames.length > 1) { //若是有重名的須要進一步處理 Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length); for (String beanName : candidateNames) { if (containsSingleton(beanName)) { candidates.put(beanName, getBean(beanName, requiredType, args)); } else { candidates.put(beanName, getType(beanName)); } } String candidateName = determinePrimaryCandidate(candidates, requiredType); if (candidateName == null) { candidateName = determineHighestPriorityCandidate(candidates, requiredType); } if (candidateName != null) { Object beanInstance = candidates.get(candidateName); if (beanInstance instanceof Class) { beanInstance = getBean(candidateName, requiredType, args); } return new NamedBeanHolder<T>(candidateName, (T) beanInstance); } throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet()); } return null; }
bean的名稱存放在
/** List of bean definition names, in registration order */ private volatile List<String> beanDefinitionNames = new ArrayList<String>(256);
四、上面找到beanName
以後調用org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>, java.lang.Object...)
實例化bean
。
參考:
Spring源碼系列:依賴注入(一)(AbstractBeanFactory-getBean)
Spring的Bean-singleton模式
作一個合格的程序猿之淺析Spring IoC源碼(十一)Spring refresh()方法解析之一
doGetBean代碼的執行順序是:
1 首先先去實例化好的bean中去找,若是找到,直接返回
2 而後去當前beanfactory中父類factory找,若是能找到父類的factory,則叫父類去返回,(與jvm的classloader的雙親加載比較像~)
3 若是都沒有找到,則開始初次實例化,先標記開始實例化
4 開始查看當前要實例化的bean是否依賴於其餘的bean,若是依賴,則先實例化依賴的bean,若是依賴的bean還依賴於其餘的bean,則接着遞歸建立
5 若是建立的bean是單例(spring默認單例)接着建立
/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @return an instance of the bean * @throws BeansException if the bean could not be created */ public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException { return doGetBean(name, requiredType, args, false); }
調用了
/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */ @SuppressWarnings("unchecked") protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons.在已經實例化的bean的緩存中查找 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference.多是循環依賴了 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory.檢查當前beanFactory是否有該實例 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); if (args != null) { // Delegation to parent with explicit args.若是沒有,去父beanFactory實例化 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. //若是該類有依賴的bean,先實例化依賴的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } registerDependentBean(dep, beanName); getBean(dep); } } // Create bean instance.進行實例化 if (mbd.isSingleton()) { //單例的bean在此處實例化 //此處調用org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)實例化 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) {//prototype類型的bean在這裏實例化 // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) { cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); } catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
五、上面調用了org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
對單例bean進行實例化,在該步因爲bean已經在AbstractApplicationContext構造方法執行時調用refresh對非懶加載的bean已經實例化,所以這裏直接從緩存singletonObjects中獲取bean實例並返回。下面的第六、7步是bean未實例化時進行實例化的主要流程(refresh實例化bean時也是調用這個流程)。
源碼以下:
/** * Return the (raw) singleton object registered under the given name, * creating and registering a new one if none registered yet. * @param beanName the name of the bean * @param singletonFactory the ObjectFactory to lazily create the singleton * with, if necessary * @return the registered singleton object */ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { //此處的singletonFactory是傳入的new ObjectFactory<Object>()匿名類 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { //若是是新的bean實例,添加到緩存singletonObjects中 addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
上面代碼中的匿名類是在第4步中傳入的,這裏再次給出源碼:
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } } });
因此實例化調用的是上面的getObject()
方法。
添加到緩存的源碼以下。注意添加緩存後,在後續實例化bean前先在緩存中查找,若是存在直接返回實例化的bean。
如org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
調用了org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)
來獲取緩存的bean
實例。
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingleton /** * Add the given singleton object to the singleton cache of this factory. * <p>To be called for eager registration of singletons. * @param beanName the name of the bean * @param singletonObject the singleton object */ protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT)); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
六、這裏調用了org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
方法實例化bean
。
注:要查找createBean方法須要在DefaultListableBeanFactory類中查找,注意參數個數
/** * Central method of this class: creates a bean instance, * populates the bean instance, applies post-processors, etc. * @see #doCreateBean */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. //若是實現了 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } //進行實例化 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
七、上面調用了org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
實例化bean
。根據註釋,該方法是Actually create the specified bean
。
/** * Actually create the specified bean. Pre-creation processing has already happened * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks. * <p>Differentiates between default bean instantiation, use of a * factory method, and autowiring a constructor. * @param beanName the name of the bean * @param mbd the merged bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return a new instance of the bean * @throws BeanCreationException if the bean could not be created * @see #instantiateBean * @see #instantiateUsingFactoryMethod * @see #autowireConstructor */ protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //一、使用合適的構造函數對bean進行實例化 // Create a new instance for the specified bean, using an appropriate instantiation strategy: //factory method, constructor autowiring, or simple instantiation. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //二、這裏進行bean初始化,設置屬性值 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 三、初始化 exposedObject = initializeBean(beanName, exposedObject, mbd); } } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
三個關鍵方法源碼
使用構造器初始化bean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance /** * Create a new instance for the specified bean, using an appropriate instantiation strategy: * factory method, constructor autowiring, or simple instantiation. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param args explicit arguments to use for constructor or factory method invocation * @return BeanWrapper for the new instance * @see #instantiateUsingFactoryMethod * @see #autowireConstructor * @see #instantiateBean */ protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } else { return instantiateBean(beanName, mbd); } } // Need to determine the constructor... Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
設置bean屬性
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
/** * Populate the bean instance in the given BeanWrapper with the property values * from the bean definition. * @param beanName the name of the bean * @param mbd the bean definition for the bean * @param bw BeanWrapper with bean instance */ protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } applyPropertyValues(beanName, mbd, bw, pvs); }
能夠參考:Spring中獲取一個bean的流程-2
這裏會在bean實例化時調用實現BeanPostProcessor的方法對bean進行處理。
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition) /** * Initialize the given bean instance, applying factory callbacks * as well as init methods and bean post processors. * <p>Called from {@link #createBean} for traditionally defined beans, * and from {@link #initializeBean} for existing bean instances. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @return the initialized bean instance (potentially wrapped) * @see BeanNameAware * @see BeanClassLoaderAware * @see BeanFactoryAware * @see #applyBeanPostProcessorsBeforeInitialization * @see #invokeInitMethods * @see #applyBeanPostProcessorsAfterInitialization */ protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } //初始化 /** * Give a bean a chance to react now all its properties are set, * and a chance to know about its owning bean factory (this object). * This means checking whether the bean implements InitializingBean or defines * a custom init method, and invoking the necessary callback(s) if it does. * @param beanName the bean name in the factory (for debugging purposes) * @param bean the new bean instance we may need to initialize * @param mbd the merged bean definition that the bean was created with * (can also be {@code null}, if given an existing bean instance) * @throws Throwable if thrown by init methods or by the invocation process * @see #invokeCustomInitMethod */ protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { @Override public Object run() throws Exception { ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //InitializingBean接口方法調用 ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { invokeCustomInitMethod(beanName, bean, mbd); } } }
最後給出debug出來的Spring初始化bean的流程。
ServiceAuthToFujitsuClient.afterPropertiesSet() line: 109 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1367 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1333 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 471 AbstractAutowireCapableBeanFactory$1.run() line: 409 AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method] DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380 AbstractBeanFactory$1.getObject() line: 264 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 220 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261 -->此處實例化authorization的ref Client DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164 BeanDefinitionValueResolver.resolveReference(Object, RuntimeBeanReference) line: 269 BeanDefinitionValueResolver.resolveValueIfNecessary(Object, Object) line: 104 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues) line: 1244 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).populateBean(String, AbstractBeanDefinition, BeanWrapper) line: 1008 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 470 AbstractAutowireCapableBeanFactory$1.run() line: 409 AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method] DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380 AbstractBeanFactory$1.getObject() line: 264 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 220 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261 --->此處實例化ServiceTarget的屬性authorization DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164 BeanDefinitionValueResolver.resolveReference(Object, RuntimeBeanReference) line: 269 BeanDefinitionValueResolver.resolveValueIfNecessary(Object, Object) line: 104 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues) line: 1244 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).populateBean(String, AbstractBeanDefinition, BeanWrapper) line: 1008 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 470 AbstractAutowireCapableBeanFactory$1.run() line: 409 AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method] DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380 AbstractBeanFactory$1.getObject() line: 264 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 220 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261 --->此處實例化acsService的屬性acsServiceTarget DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164 BeanDefinitionValueResolver.resolveReference(Object, RuntimeBeanReference) line: 269 BeanDefinitionValueResolver.resolveValueIfNecessary(Object, Object) line: 104 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).applyPropertyValues(String, BeanDefinition, BeanWrapper, PropertyValues) line: 1244 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).populateBean(String, AbstractBeanDefinition, BeanWrapper) line: 1008 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 470 AbstractAutowireCapableBeanFactory$1.run() line: 409 AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method] DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380 AbstractBeanFactory$1.getObject() line: 264 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 220 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261 --->此處實例化acsService DefaultListableBeanFactory(AbstractBeanFactory).getTypeForFactoryBean(String, RootBeanDefinition) line: 1198 調用了doGetBean DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).getTypeForFactoryBean(String, RootBeanDefinition) line: 625 DefaultListableBeanFactory(AbstractBeanFactory).isTypeMatch(String, Class) line: 450 --->此處若是是factorybean類型的,會對其進行實例化 mdb變量實時值: Root bean: class [org.springframework.aop.framework.ProxyFactoryBean]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [acs-basic.xml] beanName爲acsService // Check bean class whether we're dealing with a FactoryBean. if (FactoryBean.class.isAssignableFrom(beanClass)) { if (!BeanFactoryUtils.isFactoryDereference(name)) { // If it's a FactoryBean, we want to look at what it creates, not the factory class. Class type = getTypeForFactoryBean(beanName, mbd); return (type != null && typeToMatch.isAssignableFrom(type)); } else { return typeToMatch.isAssignableFrom(beanClass); } } DefaultListableBeanFactory.getBeanNamesForType(Class, boolean, boolean) line: 223 此處會校驗全部bean(包括FactoryBean) DefaultListableBeanFactory.getBeansOfType(Class, boolean, boolean) line: 303 DefaultListableBeanFactory.getBeansOfType(Class) line: 297 ConverterFacade.afterPropertiesSet() line: 85 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).invokeInitMethods(String, Object, RootBeanDefinition) line: 1367 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).initializeBean(String, Object, RootBeanDefinition) line: 1333 DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).doCreateBean(String, RootBeanDefinition, Object[]) line: 471 AbstractAutowireCapableBeanFactory$1.run() line: 409 AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method] DefaultListableBeanFactory(AbstractAutowireCapableBeanFactory).createBean(String, RootBeanDefinition, Object[]) line: 380 AbstractBeanFactory$1.getObject() line: 264 DefaultListableBeanFactory(DefaultSingletonBeanRegistry).getSingleton(String, ObjectFactory) line: 220 DefaultListableBeanFactory(AbstractBeanFactory).doGetBean(String, Class, Object[], boolean) line: 261 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String, Class, Object[]) line: 185 DefaultListableBeanFactory(AbstractBeanFactory).getBean(String) line: 164 DMCXmlWebApplicationContext(AbstractApplicationContext).getBean(String) line: 881 DMCXmlWebApplicationContext(AbstractApplicationContext).invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) line: 534 --->實例化全部實現BeanFactoryPostProcessor的類,此處包括如下類,此時遍歷到ConverterFacade#0 --->[com.huawei.xtvmw.commons.config.ConfigAssembler, org.springframework.beans.factory.config.PropertyPlaceholderConfigurer, com.huawei.xtvmw.commons.rmi.interceptor.RemoteInvocationClassFactory#0, com.huawei.xtvmw.commons.rmi.ServiceInterceptorFactory#0, com.huawei.xtvmw.repository.spi.ConverterFacade#0, adjustSpider, org.springframework.beans.factory.config.CustomEditorConfigurer#0] DMCXmlWebApplicationContext(AbstractApplicationContext).refresh() line: 363 ContextLoader.createWebApplicationContext(ServletContext, ApplicationContext) line: 255 ContextLoader.initWebApplicationContext(ServletContext) line: 199 DMCContextLoaderServlet(ContextLoaderServlet).init() line: 81 DMCContextLoaderServlet.init() line: 48 DMCContextLoaderServlet(GenericServlet).init(ServletConfig) line: 160 StandardWrapper.initServlet(Servlet) line: 1280 StandardWrapper.loadServlet() line: 1193 StandardWrapper.load() line: 1088 StandardContext.loadOnStartup(Container[]) line: 5033 StandardContext.startInternal() line: 5317 StandardContext(LifecycleBase).start() line: 150 ContainerBase$StartChild.call() line: 1517 ContainerBase$StartChild.call() line: 1508 FutureTask$Sync.innerRun() line: 303 FutureTask<V>.run() line: 138 ThreadPoolExecutor$Worker.runTask(Runnable) line: 886 ThreadPoolExecutor$Worker.run() line: 908 Thread.run() line: 662
上面對Spring實例化bean的流程作了簡單分析,有幾個地方須要注意:
一、使用ClassPathXmlApplicationContext時,會調用refresh方法對全部非懶加載的bean實例化(默認),此後再調用getBean方法會直接從緩存獲取
二、若是設置bean爲懶加載,則bean在調用getBean等方法時纔會實例化
三、BeanFactoryPostProcessor的實例化的優先級最高
四、beanPostProcessor是能夠臨時修改bean的,它的優先級高於正常實例化bean的,若是beanPostProcessor能返回,則直接返回了 五、由二、3兩點能夠知道bean的實例化是有優先級的