Spring Bean的加载

作者:ca88编程

【Spring源码深入分析】非懒加载的Bean实例化进度(上篇),springbean

代码入口

上文【Spring源码拆解分析】Bean加载流程大概浏览,相比较详细地深入分析了Spring上下文加载的代码入口,而且在AbstractApplicationContext的refresh方法中,点出了finishBeanFactoryInitialization方法成功了对于具有非懒加载的Bean的开端化。

finishBeanFactoryInitialization方法中调用了DefaultListableBeanFactory的preInstantiateSingletons方法,本文针对preInstantiateSingletons举办分析,解读一下Spring是怎么样协会Bean实例对象出来的。

 

DefaultListableBeanFactory的preInstantiateSingletons方法

DefaultListableBeanFactory的preInstantiateSingletons方法,看名就能够猜到其意义,伊始化全部的单例Bean,看一下格局的概念:

 1 public void preInstantiateSingletons() throws BeansException {
 2     if (this.logger.isInfoEnabled()) {
 3         this.logger.info("Pre-instantiating singletons in "   this);
 4     }
 5     synchronized (this.beanDefinitionMap) {
 6         // Iterate over a copy to allow for init methods which in turn register new bean definitions.
 7         // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
 8         List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
 9         for (String beanName : beanNames) {
10             RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
11             if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
12                 if (isFactoryBean(beanName)) {
13                     final FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX   beanName);
14                     boolean isEagerInit;
15                     if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
16                         isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
17                             public Boolean run() {
18                                 return ((SmartFactoryBean) factory).isEagerInit();
19                             }
20                         }, getAccessControlContext());
21                     }
22                     else {
23                         isEagerInit = (factory instanceof SmartFactoryBean &&
24                                 ((SmartFactoryBean) factory).isEagerInit());
25                     }
26                     if (isEagerInit) {
27                         getBean(beanName);
28                     }
29                 }
30                 else {
31                     getBean(beanName);
32                 }
33             }
34         }
35     }
36 }

前方的代码相比较轻巧,依照beanName得到BeanDefinition(即Bean的定义)。由于此措施实例化的是兼具非懒加载的单例Bean,由此要实例化Bean,必须满意11行的多个概念:

(1)不是空虚的

(2)必须是单例的

(3)必须是非懒加载的

跟着轻易看一下第12行~第29行的代码,这段代码首要做的是一件业务:首先判别一下Bean是或不是FactoryBean的兑现,接着判定Bean是还是不是斯马特FactoryBean的贯彻,假设Bean是斯马特FactoryBean的贯彻並且eagerInit(这么些单词字面意思是期盼加载,找不到八个好的用语去翻译,意思就是概念了那么些Bean供给及时加载的意趣)的话,会及时实例化那些Bean。Java开垦人士不要求关切这段代码,因为SmartFactoryBean基本不会用到,笔者翻译一下Spring官方网站对于斯马特FactoryBean的定义描述:

  • FactoryBean接口的恢宏接口。接口完结并不代表是或不是总是回到单独的实例对象,举例FactoryBean.isSingleton()实现重临false的景况并不清晰地意味着每回回来的都以单独的实例对象
  • 不兑现那么些扩充接口的简单FactoryBean的贯彻,FactoryBean.isSingleton()达成重回false总是轻松地告诉大家每一趟回去的都以独自的实例对象,暴暴露来的靶子只可以够因而命令访问
  • 注意:其一接口是八个有非常用途的接口,首要用来框架之中使用与Spring相关。通常,应用提供的FactoryBean接口达成应有只须求实现简单的FactoryBean接口就能够,新办法应该出席到增添接口中去

 

代码示例

为了后面包车型大巴代码解析方便,事先小编定义贰个Bean:

 1 package org.xrq.action;
 2 
 3 import org.springframework.beans.factory.BeanClassLoaderAware;
 4 import org.springframework.beans.factory.BeanNameAware;
 5 import org.springframework.beans.factory.InitializingBean;
 6 
 7 public class MultiFunctionBean implements InitializingBean, BeanNameAware, BeanClassLoaderAware {
 8 
 9     private int    propertyA;
10     
11     private int    propertyB;
12     
13     public int getPropertyA() {
14         return propertyA;
15     }
16 
17     public void setPropertyA(int propertyA) {
18         this.propertyA = propertyA;
19     }
20 
21     public int getPropertyB() {
22         return propertyB;
23     }
24 
25     public void setPropertyB(int propertyB) {
26         this.propertyB = propertyB;
27     }
28     
29     public void initMethod() {
30         System.out.println("Enter MultiFunctionBean.initMethod()");
31     }
32 
33     @Override
34     public void setBeanClassLoader(ClassLoader classLoader) {
35         System.out.println("Enter MultiFunctionBean.setBeanClassLoader(ClassLoader classLoader)");
36     }
37 
38     @Override
39     public void setBeanName(String name) {
40         System.out.println("Enter MultiFunctionBean.setBeanName(String name)");
41     }
42 
43     @Override
44     public void afterPropertiesSet() throws Exception {
45         System.out.println("Enter MultiFunctionBean.afterPropertiesSet()");
46     }
47     
48     @Override
49     public String toString() {
50         return "MultiFunctionBean [propertyA="   propertyA   ", propertyB="   propertyB   "]";
51     }
52     
53 }

概念对应的spring.xml:

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xsi:schemaLocation="http://www.springframework.org/schema/beans
5     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
6     
7     <bean id="multiFunctionBean" class="org.xrq.action.MultiFunctionBean" init-method="initMethod" />
8     
9 </beans>

行使那几个MultiFunctionBean,大家能够用来探寻Spring加载Bean的有余编写制定。

 

doGetBean方法组织Bean流程

上边把getBean之外的代码都剖析了弹指间,看代码就可以了解,获取Bean对象实例,都以由此getBean方法,getBean方法最后调用的是DefaultListableBeanFactory的父类AbstractBeanFactory类的doGetBean方法,由此这有个别主要分析一下doGetBean方法是何许组织出贰个单例的Bean的。

看一下doGetBean方法的代码达成,相比长:

  1 protected <T> T doGetBean(
  2         final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
  3         throws BeansException {
  4 
  5     final String beanName = transformedBeanName(name);
  6     Object bean;
  7 
  8     // Eagerly check singleton cache for manually registered singletons.
  9     Object sharedInstance = getSingleton(beanName);
 10     if (sharedInstance != null && args == null) {
 11         if (logger.isDebugEnabled()) {
 12             if (isSingletonCurrentlyInCreation(beanName)) {
 13                 logger.debug("Returning eagerly cached instance of singleton bean '"   beanName  
 14                         "' that is not fully initialized yet - a consequence of a circular reference");
 15             }
 16             else {
 17                 logger.debug("Returning cached instance of singleton bean '"   beanName   "'");
 18             }
 19         }
 20         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
 21     }
 22 
 23     else {
 24         // Fail if we're already creating this bean instance:
 25         // We're assumably within a circular reference.
 26         if (isPrototypeCurrentlyInCreation(beanName)) {
 27             throw new BeanCurrentlyInCreationException(beanName);
 28         }
 29 
 30         // Check if bean definition exists in this factory.
 31         BeanFactory parentBeanFactory = getParentBeanFactory();
 32         if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
 33             // Not found -> check parent.
 34             String nameToLookup = originalBeanName(name);
 35             if (args != null) {
 36                 // Delegation to parent with explicit args.
 37                 return (T) parentBeanFactory.getBean(nameToLookup, args);
 38             }
 39             else {
 40                 // No args -> delegate to standard getBean method.
 41                 return parentBeanFactory.getBean(nameToLookup, requiredType);
 42             }
 43         }
 44 
 45         if (!typeCheckOnly) {
 46             markBeanAsCreated(beanName);
 47         }
 48 
 49         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
 50         checkMergedBeanDefinition(mbd, beanName, args);
 51 
 52         // Guarantee initialization of beans that the current bean depends on.
 53         String[] dependsOn = mbd.getDependsOn();
 54         if (dependsOn != null) {
 55             for (String dependsOnBean : dependsOn) {
 56                 getBean(dependsOnBean);
 57                 registerDependentBean(dependsOnBean, beanName);
 58             }
 59         }
 60 
 61         // Create bean instance.
 62         if (mbd.isSingleton()) {
 63             sharedInstance = getSingleton(beanName, new ObjectFactory() {
 64                 public Object getObject() throws BeansException {
 65                     try {
 66                         return createBean(beanName, mbd, args);
 67                     }
 68                     catch (BeansException ex) {
 69                         // Explicitly remove instance from singleton cache: It might have been put there
 70                         // eagerly by the creation process, to allow for circular reference resolution.
 71                         // Also remove any beans that received a temporary reference to the bean.
 72                         destroySingleton(beanName);
 73                         throw ex;
 74                     }
 75                 }
 76             });
 77             bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
 78         }
 79 
 80         else if (mbd.isPrototype()) {
 81             // It's a prototype -> create a new instance.
 82             Object prototypeInstance = null;
 83             try {
 84                 beforePrototypeCreation(beanName);
 85                 prototypeInstance = createBean(beanName, mbd, args);
 86             }
 87             finally {
 88                 afterPrototypeCreation(beanName);
 89             }
 90             bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
 91         }
 92 
 93         else {
 94             String scopeName = mbd.getScope();
 95             final Scope scope = this.scopes.get(scopeName);
 96             if (scope == null) {
 97                 throw new IllegalStateException("No Scope registered for scope '"   scopeName   "'");
 98             }
 99             try {
100                 Object scopedInstance = scope.get(beanName, new ObjectFactory() {
101                     public Object getObject() throws BeansException {
102                             beforePrototypeCreation(beanName);
103                         try {
104                             return createBean(beanName, mbd, args);
105                         }
106                         finally {
107                             afterPrototypeCreation(beanName);
108                         }
109                     }
110                 });
111                 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
112             }
113             catch (IllegalStateException ex) {
114                 throw new BeanCreationException(beanName,
115                         "Scope '"   scopeName   "' is not active for the current thread; "  
116                         "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
117                         ex);
118             }
119         }
120     }
121 
122     // Check if required type matches the type of the actual bean instance.
123     if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
124         try {
125             return getTypeConverter().convertIfNecessary(bean, requiredType);
126         }
127         catch (TypeMismatchException ex) {
128             if (logger.isDebugEnabled()) {
129                 logger.debug("Failed to convert bean '"   name   "' to required type ["  
130                         ClassUtils.getQualifiedName(requiredType)   "]", ex);
131             }
132             throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
133         }
134     }
135     return (T) bean;
136 }

首先第9行~第21行的代码,第9行的代码就不进去看了,轻便说一下:首先检查一下本地的单例缓存是不是曾经加载过Bean,没有的话再检查earlySingleton缓存是还是不是业已加载过Bean(又是early,不好找到词语翻译),未有的话实践前面包车型客车逻辑。

接着第26行~第50行,这里进行的都是局地基本的检查和省略的操作,富含bean是或不是是prototype的(prototype的Bean当前创制会抛出十三分)、是或不是抽象的、将beanName参加alreadyCreated这些Set中等。

接着第53行~第59行,大家平常在bean标签中看到depends-on那个性子,便是通过这段保障了depends-on信赖的Bean会优先于当下Bean被加载

接着第62行~第78行、第80行~第91行、第93行~第120行有四个判别,鲜明下面的MultiFunctionBean是三个单例的Bean也是本文研商的首要性,因而试行第62行~第78行的逻辑。getSingleton方法不贴了,有一对放到的决断,很简短的逻辑,着重就是调用了ObjectFactory的getObject()方法来赢得到单例Bean对象,方法的兑现是调用了createBean方法,createBean方法是AbstractBeanFactory的子类AbstractAutowireCapableBeanFactory的三个格局,看一下它的点子实现:

 1 protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
 2         throws BeanCreationException {
 3 
 4     if (logger.isDebugEnabled()) {
 5         logger.debug("Creating instance of bean '"   beanName   "'");
 6     }
 7     // Make sure bean class is actually resolved at this point.
 8     resolveBeanClass(mbd, beanName);
 9 
10     // Prepare method overrides.
11     try {
12         mbd.prepareMethodOverrides();
13     }
14     catch (BeanDefinitionValidationException ex) {
15         throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
16                 beanName, "Validation of method overrides failed", ex);
17     }
18 
19     try {
20         // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
21         Object bean = resolveBeforeInstantiation(beanName, mbd);
22         if (bean != null) {
23             return bean;
24         }
25     }
26     catch (Throwable ex) {
27         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
28                 "BeanPostProcessor before instantiation of bean failed", ex);
29     }
30 
31     Object beanInstance = doCreateBean(beanName, mbd, args);
32     if (logger.isDebugEnabled()) {
33         logger.debug("Finished creating instance of bean '"   beanName   "'");
34     }
35     return beanInstance;
36 }

前边的代码都没事儿意思,代码施行到第31行:

 1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
 2     // Instantiate the bean.
 3     BeanWrapper instanceWrapper = null;
 4     if (mbd.isSingleton()) {
 5         instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
 6     }
 7     if (instanceWrapper == null) {
 8         instanceWrapper = createBeanInstance(beanName, mbd, args);
 9     }
10     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
11     Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
12 
13     // Allow post-processors to modify the merged bean definition.
14     synchronized (mbd.postProcessingLock) {
15         if (!mbd.postProcessed) {
16             applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
17             mbd.postProcessed = true;
18         }
19     }
20 
21     // Eagerly cache singletons to be able to resolve circular references
22     // even when triggered by lifecycle interfaces like BeanFactoryAware.
23     boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
24             isSingletonCurrentlyInCreation(beanName));
25     if (earlySingletonExposure) {
26         if (logger.isDebugEnabled()) {
27             logger.debug("Eagerly caching bean '"   beanName  
28                     "' to allow for resolving potential circular references");
29         }
30         addSingletonFactory(beanName, new ObjectFactory() {
31             public Object getObject() throws BeansException {
32                 return getEarlyBeanReference(beanName, mbd, bean);
33             }
34         });
35     }
36 
37     // Initialize the bean instance.
38     Object exposedObject = bean;
39     try {
40         populateBean(beanName, mbd, instanceWrapper);
41         if (exposedObject != null) {
42             exposedObject = initializeBean(beanName, exposedObject, mbd);
43         }
44     }
45     catch (Throwable ex) {
46         if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
47             throw (BeanCreationException) ex;
48         }
49         else {
50             throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
51         }
52     }
53 
54     if (earlySingletonExposure) {
55         Object earlySingletonReference = getSingleton(beanName, false);
56         if (earlySingletonReference != null) {
57             if (exposedObject == bean) {
58                 exposedObject = earlySingletonReference;
59             }
60             else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
61                 String[] dependentBeans = getDependentBeans(beanName);
62                 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
63                 for (String dependentBean : dependentBeans) {
64                     if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
65                         actualDependentBeans.add(dependentBean);
66                     }
67                 }
68                 if (!actualDependentBeans.isEmpty()) {
69                     throw new BeanCurrentlyInCreationException(beanName,
70                             "Bean with name '"   beanName   "' has been injected into other beans ["  
71                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans)  
72                             "] in its raw version as part of a circular reference, but has eventually been "  
73                             "wrapped. This means that said other beans do not use the final version of the "  
74                             "bean. This is often the result of over-eager type matching - consider using "  
75                             "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
76                 }
77             }
78         }
79     }
80 
81     // Register bean as disposable.
82     try {
83         registerDisposableBeanIfNecessary(beanName, bean, mbd);
84     }
85     catch (BeanDefinitionValidationException ex) {
86         throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
87     }
88 
89     return exposedObject;
90 }

代码追踪到此地,已经到了主流程,接下去分段深入分析doCreateBean方法的代码。

 

创建Bean实例

第8行的createBeanInstance方法,会创立出Bean的实例,并打包为BeanWrapper,看一下createBeanInstance方法,只贴最终一段相比首要的:

 1 // Need to determine the constructor...
 2 Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
 3 if (ctors != null ||
 4         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
 5         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
 6     return autowireConstructor(beanName, mbd, ctors, args);
 7 }
 8 
 9 // No special handling: simply use no-arg constructor.
10 return instantiateBean(beanName, mbd);

乐趣是bean标签使用构造函数注入属性的话,实施第6行,否则实行第10行。MultiFunctionBean使用默许构造函数,使用setter注入属性,因而推行第10行代码:

 1 protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
 2     try {
 3         Object beanInstance;
 4         final BeanFactory parent = this;
 5         if (System.getSecurityManager() != null) {
 6             beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
 7                 public Object run() {
 8                     return getInstantiationStrategy().instantiate(mbd, beanName, parent);
 9                 }
10             }, getAccessControlContext());
11         }
12         else {
13             beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
14         }
15         BeanWrapper bw = new BeanWrapperImpl(beanInstance);
16         initBeanWrapper(bw);
17         return bw;
18     }
19     catch (Throwable ex) {
20         throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
21     }
22 }

代码实行到13行:

 1 public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
 2     // Don't override the class with CGLIB if no overrides.
 3     if (beanDefinition.getMethodOverrides().isEmpty()) {
 4         Constructor<?> constructorToUse;
 5         synchronized (beanDefinition.constructorArgumentLock) {
 6             constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
 7             if (constructorToUse == null) {
 8                 final Class clazz = beanDefinition.getBeanClass();
 9                 if (clazz.isInterface()) {
10                     throw new BeanInstantiationException(clazz, "Specified class is an interface");
11                 }
12                 try {
13                     if (System.getSecurityManager() != null) {
14                         constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
15                             public Constructor run() throws Exception {
16                                 return clazz.getDeclaredConstructor((Class[]) null);
17                             }
18                         });
19                     }
20                     else {
21                         constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
22                     }
23                     beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
24                 }
25                 catch (Exception ex) {
26                     throw new BeanInstantiationException(clazz, "No default constructor found", ex);
27                 }
28             }
29         }
30         return BeanUtils.instantiateClass(constructorToUse);
31     }
32     else {
33         // Must generate CGLIB subclass.
34         return instantiateWithMethodInjection(beanDefinition, beanName, owner);
35     }
36 }

整段代码都在做一件工作,正是选拔四个施用的构造函数。当然第9行顺带做了二个判断:实例化二个接口将报错。

末尾调用到30行,看一下代码:

 1 public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
 2     Assert.notNull(ctor, "Constructor must not be null");
 3     try {
 4         ReflectionUtils.makeAccessible(ctor);
 5         return ctor.newInstance(args);
 6     }
 7     catch (InstantiationException ex) {
 8         throw new BeanInstantiationException(ctor.getDeclaringClass(),
 9                 "Is it an abstract class?", ex);
10     }
11     catch (IllegalAccessException ex) {
12         throw new BeanInstantiationException(ctor.getDeclaringClass(),
13                 "Is the constructor accessible?", ex);
14     }
15     catch (IllegalArgumentException ex) {
16         throw new BeanInstantiationException(ctor.getDeclaringClass(),
17                 "Illegal arguments for constructor", ex);
18     }
19     catch (InvocationTargetException ex) {
20         throw new BeanInstantiationException(ctor.getDeclaringClass(),
21                 "Constructor threw exception", ex.getTargetException());
22     }
23 }

通过反射生成Bean的实例。看到日前有一步makeAccessible,那象征不畏Bean的构造函数是private、protected的,依旧不影响Bean的结构

最后注意一下,这里被实例化出来的Bean并不会间接回到,而是会被打包为BeanWrapper继续在后边使用。

 

代码入口 上文【Spring源码剖判】Bean加载流程大概浏览,比较详细地解析了Spri...

Spring IoC容器的宏图

1,举个例子以下图,IoC容器的接口设计图。

    

图片 1

2,简介

    -1,从BeanFactory到HierarchicalbeanFactory再到ConfigurableBeanFactory是一条为主的BeanFactory设计路线。BeanFactory定义了核心的IoC容器接口。

HierarchicalBeanFactory接口承袭了BeanFactory接口,并再其基础上加多了getParentBeanFactory()接口作用,使得BeanFactory具有双亲IoC管理作用。ConfigurableBeanFactory首要定义了对BeanFactory的配置效果与利益。

    -2。以ApplicationContext为主题的接口设计。

public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isInfoEnabled()) {
            this.logger.info("Pre-instantiating singletons in "   this);
        }
        List<String> beanNames;
        synchronized (this.beanDefinitionMap) {
            // Iterate over a copy to allow for init methods which in turn register new bean definitions.
            // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
            beanNames = new ArrayList<String>(this.beanDefinitionNames);
        }
        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX   beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }
    }

        ↓↓

ApplicationContext和Bean的起首化及销毁

    ​ApplicationContext的开发银行是在AbstractApplicationContext中完成。

    ​同样的绝迹操作是在doClose()方法中甘休。

protected void doClose() {        boolean actuallyClose;     synchronized (this.activeMonitor) {          actuallyClose = this.active && !this.closed;            this.closed = true;        }
      if (actuallyClose) {           if (logger.isInfoEnabled()) {                logger.info("Closing "   this);          }
          LiveBeansView.unregisterApplicationContext(this);
          try {              // Publish shutdown event.               publishEvent(new ContextClosedEvent(this));           }            catch (Throwable ex) {             logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);          }
          // Stop all Lifecycle beans, to avoid delays during individual destruction.          try {              getLifecycleProcessor().onClose();         }            catch (Throwable ex) {             logger.warn("Exception thrown from LifecycleProcessor on context close", ex);          }
          // Destroy all cached singletons in the context's BeanFactory.           destroyBeans();
          // Close the state of this context itself.           closeBeanFactory();
          // Let subclasses do some final clean-up if they wish...         onClose();
          synchronized (this.activeMonitor) {              this.active = false;           }        }    }

    ​Bean的绝迹和创建,Spring通过IoC管理Bean的生命周期来落到实处。

Spring中Bean的生命周期富含:

    ​    ​-1。Bean实例的创造。

    ​    ​-2,为Bean实例设置属性。

    ​    ​-3。调用Bean的初步化方法。

    ​    ​-4,通过IoC获取Bean。

    ​    ​-5,当容器关闭的时候调用bean的绝迹方法。

   图片 2

        ↓↓

IoC容器的开首化进度

    一句话来说IoC的初阶化是由AbstractApplicationContext的refresh方法达成的。整个运营进程富含八个部分。BeanDefinition的Resource定位、加载和注冊多少个为主部分。Spring将多个模块分开。并动用差异的模块达成。

    第一个经过是Resource定位进度。那一个Resource定位是指Spring找到大家定义的Bean配置的xml文件。

    第二步。BeanDefinition的加载。那些进程是把用户定义好的Bean表示成IoC容器内部的数据结构,而这一个数据结构正是BeanDefinition。详细说。BeanDefination实际正是POJO在容器中的抽象,通过那一个BeanDefinition定义的数据结构,使IoC容器能够平价的对POJO对象。也等于Bean实行田间管理。

    第三步,是向IoC容器注冊这个BeanDefinition的经过。那些进度通过调用BeanDefinationRegistry接口达成。

这些注冊进程把加载进度(第二步)获得的BeanDefinition向容器注冊。IoC内部,将BeanDefinition注入到几个HashMap中去,IoC容器正是通过HashMap来持有这么些BeanDefinition数据的。

    一般,IoC的开头化进程,不分包信赖注入。注重注入一般产生在使用第四回经过getBean向容器获取Bean的时候。

1,BeanDefinition的Resource定位。

  在运用DefaultListableBeanFactory的时候,首先必须使用Resource来实行能源一定容器使用的BeanDefinition。

    使用ClassPathResource实行财富一定。

ClassPathResource re = new ClassPathResource("bean.xml");

    在此地定义的财富文件不能被DefaultListableBeanFactory直接行使,通过BeanDefinitionReader来读取。

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();XmlBeanDefinitionReader xdr = new XmlBeanDefinitionReader(beanFactory);xdr.loadBeanDefinitions(re);

在那边大家开采采取比較麻烦。所以利用ApplicationContext,由于在ApplicationContext中。Spring为大家提供了一多种的财富一定,比如FileSystemXmlApplicationContext。

    以FileSystemXmlApplicationContext为例,解说相应的源代码。

    该构造函数通过文件路劲来扭转对应的FileSystemXmlApplicationContext

public FileSystemXmlApplicationContext(String configLocation) throws BeansException {       this(new String[] {configLocation}, true, null);    }

由此refresh方法来加载BeanDefinition。

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)           throws BeansException {
       super(parent);       setConfigLocations(configLocations);        if (refresh) {          refresh();        } }

经过文件系统来获取能源。

@Override  protected Resource getResourceByPath(String path) {      if (path != null && path.startsWith("/")) {           path = path.substring(1);       }     return new FileSystemResource(path);    }

2,BeanDefinition的加载和剖判。

    对IoC容器来讲。加载进程也便是把BeanDefinition在IoC容器中间转播换来一个Spring内部数据结构的经过。IoC对目的的田管都是透过对其具备的BeanDefination实行相关操作来促成的。

这么些BeanDefinition是透过HashMap来保证的。

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)           throws BeansException {      super(parent);       setConfigLocations(configLocations);        if (refresh) {          refresh();        } }

    如上代码,refresh()方法运维了容器开首化。是加载BeanDefination的入口方法。
    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.
//在子类中启动refreshBeanFactory()的地方。            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.
//设置BeanFactory的后置处理。
               postProcessBeanFactory(beanFactory);
               // Invoke factory processors registered as beans in the context.
//调用BeanFactory的后置处理器。这些处理器是在Bean定义中向容器注冊的
             invokeBeanFactoryPostProcessors(beanFactory);
               // Register bean processors that intercept bean creation.
//注冊Bean的后处理器。在Bean的创建过程中调用
             registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//对上下文中的消息源初始化
             initMessageSource();
               // Initialize event multicaster for this context.
//初始化上下文中的时间机制                initApplicationEventMulticaster();
               // Initialize other special beans in specific context subclasses.
//初始化其它Bean
             onRefresh();
               // Check for listener beans and register them.
//检查监听bean并注冊
             registerListeners();
               // Instantiate all remaining (non-lazy-init) singletons.
//实例化全部(non-lazy-init) 单例。                finishBeanFactoryInitialization(beanFactory);
               // Last step: publish corresponding event.
//公布容器事件。结束
             finishRefresh();          }
           catch (BeansException ex) {             // Destroy already created singletons to avoid dangling resources.
//防止Bean资源占用,销毁已经创建的单例。                destroyBeans();
               // Reset 'active' flag.
//重置active标志
             cancelRefresh(ex);
               // Propagate exception to caller.             throw ex;           }     } }

-1。prepareRefresh():

/**  * Prepare this context for refreshing, setting its startup date and     * active flag as well as performing any initialization of property sources.     */ protected void prepareRefresh() {      this.startupDate = System.currentTimeMillis();
      synchronized (this.activeMonitor) {          this.active = true;        }
      if (logger.isInfoEnabled()) {            logger.info("Refreshing "   this);       }
      // Initialize any placeholder property sources in the context environment        initPropertySources();
      // Validate that all properties marked as required are resolvable        // see ConfigurablePropertyResolver#setRequiredProperties        getEnvironment().validateRequiredProperties(); }

-2。启动refreshBeanFactory():

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();



/**  * Tell the subclass to refresh the internal bean factory.   * @return the fresh BeanFactory instance    * @see #refreshBeanFactory()    * @see #getBeanFactory()    */ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {      refreshBeanFactory();        ConfigurableListableBeanFactory beanFactory = getBeanFactory();     if (logger.isDebugEnabled()) {           logger.debug("Bean factory for "   getDisplayName()   ": "   beanFactory);      }        return beanFactory;    }

好不轻巧调用,AbstractRefreshableApplicationContext中的refreshBeanFactory()方法。

  /**   * This implementation performs an actual refresh of this context's underlying   * bean factory, shutting down the previous bean factory (if any) and    * initializing a fresh bean factory for the next phase of the context's lifecycle.  */ @Override    protected final void refreshBeanFactory() throws BeansException {       if (hasBeanFactory()) {//假设已经存在BeanFactory           destroyBeans();//销毁            closeBeanFactory();      }        try { //创建IoC容器            DefaultListableBeanFactory beanFactory = createBeanFactory();           beanFactory.setSerializationId(getId());         customizeBeanFactory(beanFactory);         loadBeanDefinitions(beanFactory);//加载BeanFactory。抽象方法         synchronized (this.beanFactoryMonitor) {             this.beanFactory = beanFactory;           }        }        catch (IOException ex) {           throw new ApplicationContextException("I/O error parsing bean definition source for "   getDisplayName(), ex);      }    }

此处调用的loadBeanDefinations()是二个虚无方法,详细实近期AbstractXmlApplicationContext。

/**  * Loads the bean definitions via an XmlBeanDefinitionReader.    * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader    * @see #initBeanDefinitionReader    * @see #loadBeanDefinitions     */ @Override    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {       // Create a new XmlBeanDefinitionReader for the given BeanFactory.       XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
      // Configure the bean definition reader with this context's      // resource loading environment.     beanDefinitionReader.setEnvironment(this.getEnvironment());        beanDefinitionReader.setResourceLoader(this);        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
      // Allow a subclass to provide custom initialization of the reader,      // then proceed with actually loading the bean definitions.      initBeanDefinitionReader(beanDefinitionReader);        loadBeanDefinitions(beanDefinitionReader); }

接着正是调用loadBeanDefinations的地点,首先获得BeanDefinition新闻的Resource定位,然后调用XmlBeanDefinitionReader来读取,详细进程托付给BeanDefinitionReader来终结的。

XML文件则是通过XmlBeanDefinitionReader来加载BeanDefination到容器中。

    ​注:在XmlBeanDefinationReader中找到的loadBeanDefination()方法。与书中的代码块分裂。

这里大概是Spring版本号的主题材料。

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {      Assert.notNull(encodedResource, "EncodedResource must not be null");        if (logger.isInfoEnabled()) {            logger.info("Loading XML bean definitions from "   encodedResource.getResource());        }
      Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();        if (currentResources == null) {           currentResources = new HashSet<EncodedResource>(4);           this.resourcesCurrentlyBeingLoaded.set(currentResources);       }        if (!currentResources.add(encodedResource)) {          throw new BeanDefinitionStoreException(                  "Detected cyclic loading of "   encodedResource   " - check your import definitions!");     }        try {//输入流读取资源            InputStream inputStream = encodedResource.getResource().getInputStream();           try {              InputSource inputSource = new InputSource(inputStream);             if (encodedResource.getEncoding() != null) {                  inputSource.setEncoding(encodedResource.getEncoding());                }//调用解析XML文件               return doLoadBeanDefinitions(inputSource, encodedResource.getResource());            }            finally {              inputStream.close();           }        }        catch (IOException ex) {           throw new BeanDefinitionStoreException(                  "IOException parsing XML document from "   encodedResource.getResource(), ex);       }        finally {          currentResources.remove(encodedResource);            if (currentResources.isEmpty()) {                this.resourcesCurrentlyBeingLoaded.remove();          }        }    }

doLoadBeanDefinitions()方法:

    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)           throws BeanDefinitionStoreException {       try {                    //载入文件         Document doc = doLoadDocument(inputSource, resource);                    //启动具体的解析过程          return registerBeanDefinitions(doc, resource);     }        catch (BeanDefinitionStoreException ex) {          throw ex;      }        catch (SAXParseException ex) {         throw new XmlBeanDefinitionStoreException(resource.getDescription(),                 "Line "   ex.getLineNumber()   " in XML document from "   resource   " is invalid", ex);        }        catch (SAXException ex) {          throw new XmlBeanDefinitionStoreException(resource.getDescription(),                 "XML document from "   resource   " is invalid", ex);     }        catch (ParserConfigurationException ex) {          throw new BeanDefinitionStoreException(resource.getDescription(),                    "Parser configuration exception parsing XML from "   resource, ex);        }        catch (IOException ex) {           throw new BeanDefinitionStoreException(resource.getDescription(),                    "IOException parsing XML document from "   resource, ex);      }        catch (Throwable ex) {         throw new BeanDefinitionStoreException(resource.getDescription(),                    "Unexpected exception parsing XML document from "   resource, ex);     }    }

registerbeanDefinitions()方法代码:

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {         //获取XML文档读取        BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();     documentReader.setEnvironment(this.getEnvironment());      int countBefore = getRegistry().getBeanDefinitionCount();             //详细解析过程        documentReader.registerBeanDefinitions(doc, createReaderContext(resource));      return getRegistry().getBeanDefinitionCount() - countBefore; }

BeanDefinition加载进度中,首先调用XML分析器,生成XML深入分析对象。然后再进行详尽的辨析。

createBeanDefinitionDocumentReader()方法:

    protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {     return BeanDefinitionDocumentReader.class.cast(BeanUtils.instantiateClass(this.documentReaderClass)); }

取获得详细的深入分析器。然后托付给BeanDefinitionParserDelegate来终止详细的辨析。比方以下查看DefaultBeanDefinitionDocuement里德r中的processBeanDefinition(Element , BeanDefinitionParserDelegate)方法:

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {       BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
//BeanDefinitionHolder是对BeanDefinition的封装。
        if (bdHolder != null) {           bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);         try {                // Register the final decorated instance.
//向IoC容器注冊解析到的BeanDefinition。               BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());            }            catch (BeanDefinitionStoreException ex) {              getReaderContext().error("Failed to register bean definition with name '"                         bdHolder.getBeanName()   "'", ele, ex);         }            // Send registration event.          getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));      }    }

BeanDefinitionHolder:

public class BeanDefinitionHolder implements BeanMetadataElement {
  private final BeanDefinition beanDefinition;
  private final String beanName;
  private final String[] aliases;
........

在BeanDefinitionParserDelegate类中,定义了对种种SpringBean类的拍卖。

查阅其相应的parseBeanDefinitionElement方法:

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {      String id = ele.getAttribute(ID_ATTRIBUTE);//bean元素中的ID      String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);//bean元素中的name
      List<String> aliases = new ArrayList<String>();//aliases      if (StringUtils.hasLength(nameAttr)) {            String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);          aliases.addAll(Arrays.asList(nameArr));     }
      String beanName = id;       if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {           beanName = aliases.remove(0);          if (logger.isDebugEnabled()) {               logger.debug("No XML 'id' specified - using '"   beanName                       "' as bean name and "   aliases   " as aliases");           }        }
      if (containingBean == null) {         checkNameUniqueness(beanName, aliases, ele);       }
      AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);//具体解析过程,返回AbstractBeanDefinition对象,该对象定义了Bean的基本属性     if (beanDefinition != null) {         if (!StringUtils.hasText(beanName)) {             try {                  if (containingBean != null) {                     beanName = BeanDefinitionReaderUtils.generateBeanName(                               beanDefinition, this.readerContext.getRegistry(), true);                   }                    else {                     beanName = this.readerContext.generateBeanName(beanDefinition);                       // Register an alias for the plain bean class name, if still possible,                       // if the generator returned the class name plus a suffix.                       // This is expected for Spring 1.2/2.0 backwards compatibility.                      String beanClassName = beanDefinition.getBeanClassName();                     if (beanClassName != null &&                             beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&                             !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {                          aliases.add(beanClassName);                      }                    }                    if (logger.isDebugEnabled()) {                       logger.debug("Neither XML 'id' nor 'name' specified - "                               "using generated bean name ["   beanName   "]");                    }                }                catch (Exception ex) {                 error(ex.getMessage(), ele);                   return null;                }            }            String[] aliasesArray = StringUtils.toStringArray(aliases);          return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);       }
      return null;    }

翻开详细的深入分析代码,parseBeanDefinitionEleent方法:

public AbstractBeanDefinition parseBeanDefinitionElement(          Element ele, String beanName, BeanDefinition containingBean) {
      this.parseState.push(new BeanEntry(beanName));
      String className = null;     if (ele.hasAttribute(CLASS_ATTRIBUTE)) {           className = ele.getAttribute(CLASS_ATTRIBUTE).trim();        }
      try {          String parent = null;            if (ele.hasAttribute(PARENT_ATTRIBUTE)) {              parent = ele.getAttribute(PARENT_ATTRIBUTE);           }                       //生成BeanDefinition对象          AbstractBeanDefinition bd = createBeanDefinition(className, parent);                   //解析属性,并设置Description信息         parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));                     //解析bean元素信息            parseMetaElements(ele, bd);          parseLookupOverrideSubElements(ele, bd.getMethodOverrides());          parseReplacedMethodSubElements(ele, bd.getMethodOverrides());                   //构造函数          parseConstructorArgElements(ele, bd);                 //成员变量          parsePropertyElements(ele, bd);          parseQualifierElements(ele, bd);                         bd.setResource(this.readerContext.getResource());            bd.setSource(extractSource(ele));
          return bd;     }        catch (ClassNotFoundException ex) {            error("Bean class ["   className   "] not found", ele, ex);      }        catch (NoClassDefFoundError err) {         error("Class that bean class ["   className   "] depends on not found", ele, err);       }        catch (Throwable ex) {         error("Unexpected failure during bean definition parsing", ele, ex);       }        finally {          this.parseState.pop();        }
      return null;    }

当中相应的各类非常音讯,大概大家在编制程序工作中平日遇到。

    public void parsePropertyElements(Element beanEle, BeanDefinition bd) {     NodeList nl = beanEle.getChildNodes();        for (int i = 0; i < nl.getLength(); i  ) {          Node node = nl.item(i);         if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) {                parsePropertyElement((Element) node, bd);//解析           }        }    }



/**  * Parse a property element.     */ public void parsePropertyElement(Element ele, BeanDefinition bd) {      String propertyName = ele.getAttribute(NAME_ATTRIBUTE);//获取property名字       if (!StringUtils.hasLength(propertyName)) {           error("Tag 'property' must have a 'name' attribute", ele);           return;       }        this.parseState.push(new PropertyEntry(propertyName));     try {          if (bd.getPropertyValues().contains(propertyName)) {//是否包括               error("Multiple 'property' definitions for property '"   propertyName   "'", ele);             return;           }            Object val = parsePropertyValue(ele, bd, propertyName);//解析         PropertyValue pv = new PropertyValue(propertyName, val);//获取值            parseMetaElements(ele, pv);          pv.setSource(extractSource(ele));          bd.getPropertyValues().addPropertyValue(pv);       }        finally {          this.parseState.pop();        }    }

public Object parsePropertyValue(Element ele, BeanDefinition bd, String propertyName) {      String elementName = (propertyName != null) ?                      "<property> element for property '"   propertyName   "'" :                     "<constructor-arg> element";
      // Should only have one child element: ref, value, list, etc.        NodeList nl = ele.getChildNodes();//xml文档解析       Element subElement = null;       for (int i = 0; i < nl.getLength(); i  ) {          Node node = nl.item(i);         if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) &&                  !nodeNameEquals(node, META_ELEMENT)) {               // Child element is what we're looking for.              if (subElement != null) {                 error(elementName   " must not contain more than one sub-element", ele);                }                else {                 subElement = (Element) node;              }            }        }
      boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);//是否是ref引用      boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);//值引用     if ((hasRefAttribute && hasValueAttribute) ||                ((hasRefAttribute || hasValueAttribute) && subElement != null)) {         error(elementName                      " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele);     }
      if (hasRefAttribute) {//ref引用            String refName = ele.getAttribute(REF_ATTRIBUTE);           if (!StringUtils.hasText(refName)) {              error(elementName   " contains empty 'ref' attribute", ele);            }            RuntimeBeanReference ref = new RuntimeBeanReference(refName);           ref.setSource(extractSource(ele));         return ref;        }//value 引用        else if (hasValueAttribute) {            TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));         valueHolder.setSource(extractSource(ele));         return valueHolder;        }//假设还有子元素。触发对子元素的解析      else if (subElement != null) {          return parsePropertySubElement(subElement, bd);        }        else {         // Neither child element nor "ref" or "value" attribute found.           error(elementName   " must specify a ref or value", ele);           return null;        }    }

3,BeanDefinition在IoC容器中的注冊

BeanDefinition完毕加载和深入分析进度后。要求对其进展注冊操作。

注冊是在DefaultListableBeanFactory中,通过HashMap来加载Beandefinition的。

/** Map of bean definition objects, keyed by bean name */   private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);

调用顺序:XmlBeanDefinitionReader调用loadBeanDefinitions(EncodedResource)方法,然后到registerBeanDefinitions()方法。在该方法中registerBeanDefinitions()方法被调用。在DefaultListableBeanFactory中,完结了BeanDefinitionRegistry接口。

@Override   public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)            throws BeanDefinitionStoreException {
      Assert.hasText(beanName, "Bean name must not be empty");        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
      if (beanDefinition instanceof AbstractBeanDefinition) {          try {              ((AbstractBeanDefinition) beanDefinition).validate();         }            catch (BeanDefinitionValidationException ex) {             throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,                      "Validation of bean definition failed", ex);            }        }
      synchronized (this.beanDefinitionMap) {//是否存在同样名字            BeanDefinition oldBeanDefinition = this.beanDefinitionMap.get(beanName);           if (oldBeanDefinition != null) {              if (!this.allowBeanDefinitionOverriding) {                   throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,                          "Cannot register bean definition ["   beanDefinition   "] for bean '"   beanName                           "': There is already ["   oldBeanDefinition   "] bound.");              }                else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {                    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE                    if (this.logger.isWarnEnabled()) {                     this.logger.warn("Overriding user-defined bean definition for bean '"   beanName                               " with a framework-generated bean definition ': replacing ["                               oldBeanDefinition   "] with ["   beanDefinition   "]");                   }                }                else {                 if (this.logger.isInfoEnabled()) {                     this.logger.info("Overriding bean definition for bean '"   beanName                                "': replacing ["   oldBeanDefinition   "] with ["   beanDefinition   "]");                    }                }            }            else {//注冊bean。将bean的name放入List               this.beanDefinitionNames.add(beanName);             this.frozenBeanDefinitionNames = null;           }
//map中增加         this.beanDefinitionMap.put(beanName, beanDefinition);     }
      resetBeanDefinition(beanName); }

告竣了注冊。就归西了IoC容器的开始化。

在行使的IoC容器的DefaultListableBeanFactory中早就制造了Bean的安插信息,何况那些BeanDefinition已经能够被容器使用,他们都在beanDefinitionMap中被寻找和使用。容器的遵循正是对这一个音信举办维护和管理。

我们那边来看最根本的创设bean实例对象的办法doCreateBean();

 

BeanFactory的使用场景

    BeanFactory是最要害的IoC容器。

    用户在动用容器的时候能够因而&符来博取FactoryBean本人。FactoryBean跟普通Bean分化。通过BeanFactory类的getBean方法直接拿走到的不要该FactoryBean的实例,而是 该FactoryBean中方法getObject再次回到的目的。

但大家能够由此别的渠道得到到该FactoryBean的实例。方法就是在经过 getBean方法赢得实例时在參数name后边加上“&”符号就能够。

    

String FACTORY_BEAN_PREFIX = "&";

    1。BeanFactory的第一接口,以及其效率举个例子以下:

    -1。容器预计是或不是包蕴钦点名字的bean。

boolean containsBean(String name);

    -2,预计钦赐的bean是或不是是prototype类型。

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

    -3。估算钦点的bean是还是不是是singleton。

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

    -4,揣度钦点的bean是或不是与给定类型相相配。

boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;

    -5,获取钦点Bean的品类。

Class<?> getType(String name) throws NoSuchBeanDefinitionException;

    -6。钦点bean的一体别称。

String[] getAliases(String name);

2,BeanFactory的器皿设计原理。

    BeanFactory接口提供了使用IoC的专门的学问,况兼Spring实现了一文山会海容器的落实供开荒者使用。

以XmlBeanFactory为例。比方以下为XmlBeanFactory的持续结构图。

图片 3

上边是XmlBeanFactory的代码,在Spring 4中。该类已经不推荐被使用了。

@Deprecated@SuppressWarnings({"serial", "all"})public class XmlBeanFactory extends DefaultListableBeanFactory {
   private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);

   /**    * 通过给定的资源创建一个XmlBeanFactory实例。     */  public XmlBeanFactory(Resource resource) throws BeansException {       this(resource, null);   }
   /**    * Create a new XmlBeanFactory with the given input stream,   * which must be parsable using DOM.  */  public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {       super(parentBeanFactory);        this.reader.loadBeanDefinitions(resource);   }
}

    该类承继了DefaultListableBeanFactory类。DefaultListableBeanFactory该类完成三个无比基础的IoC容器。

    举例以下是五个简单易行的运用办法比如:

ClassPathResource re = new ClassPathResource("bean.xml");     DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();     XmlBeanDefinitionReader xdr = new XmlBeanDefinitionReader(beanFactory);      xdr.loadBeanDefinitions(re);      System.out.println(xdr.getRegistry());
package cn.test.service.impl;

import cn.test.service.TestService;
import cn.test.service.TestService2;

public class TestServiceImpl implements TestService{


    private TestServiceImpl(){
        System.out.println("xx");
    }

    private TestService2 testService2;

    public TestService2 getTestService2() {
        return testService2;
    }

    public void setTestService2(TestService2 testService2) {
        this.testService2 = testService2;
    }

}

 

IoC容器的依赖注入    ​    ​

    ​信赖注入是用户率先次向Ioc容器索要Bean的时候接触的。除非通过lazy-init调整Bean的记叙时机。

    ​从DefaultListableBeanFactory的基类AbstractBeanFactory的getBean方法開始查看达成。

@Override   public Object getBean(String name) throws BeansException {     return doGetBean(name, null, null, false);    }
  @Override    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {        return doGetBean(name, requiredType, null, false);   }
  @Override    public Object getBean(String name, Object... args) throws BeansException {     return doGetBean(name, null, args, false);   }

查看doGetBean方法:

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   "'");            }        }        //对FactoryBean的处理,获取FactoryBean的相关实例。     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.      //减产是否已经存在相应的BeanDefinition对象     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.              return (T) parentBeanFactory.getBean(nameToLookup, args);            }            else {             // No args -> delegate to standard getBean method.                return parentBeanFactory.getBean(nameToLookup, requiredType);            }        }
      if (!typeCheckOnly) {          markBeanAsCreated(beanName);       }
      try {          //依据Bean的名字获取BeanDefinition         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 dependsOnBean : dependsOn) {                 if (isDependent(beanName, dependsOnBean)) {                        throw new BeanCreationException("Circular depends-on relationship between '"                                beanName   "' and '"   dependsOnBean   "'");                  }                    registerDependentBean(dependsOnBean, beanName);//注冊依赖bean                 getBean(dependsOnBean);//获取bean的递归调用               }            }
          // Create bean instance.         //创建单例bean           if (mbd.isSingleton()) {             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()) {// property 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();//其它scope              final Scope scope = this.scopes.get(scopeName);              if (scope == null) {                  throw new IllegalStateException("No Scope registered for scope '"   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.  //检查bean的类型。   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;}

这种措施就是借助注入的输入,由于他接触了依据注入。

即使能够以最轻松易行的章程来形容陈诉Spring IoC容器,即Spring容器就是多少个HashMap,通过HashMap来处理BeanDefinition对象。

在getBean()的时候,会触发createBean()来进创造要求的Bean对象。

    ​终于的调用,到AbstractAutowireCapableBeanFactory的createBean()方法,代码举例以下:

/**  * Central method of this class: creates a bean instance,    * populates the bean instance, applies post-processors, etc.    * @see #doCreateBean    */ @Override    protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)          throws BeanCreationException {
      if (logger.isDebugEnabled()) {           logger.debug("Creating instance of bean '"   beanName   "'");      }      // Make sure bean class is actually resolved at this point.
//推断须要创建的Bean是否可实例化,这个类是否可通过类装载器来加载        resolveBeanClass(mbd, beanName);
      // Prepare method overrides.     try {          mbd.prepareMethodOverrides();      }        catch (BeanDefinitionValidationException ex) {         throw new BeanDefinitionStoreException(mbd.getResourceDescription(),                 beanName, "Validation of method overrides failed", ex);       }
      try {            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//假设Bean配置了BeanPostProcessors,则返回代理对象          Object bean = resolveBeforeInstantiation(beanName, mbd);            if (bean != null) {               return bean;           }        }        catch (Throwable ex) {         throw new BeanCreationException(mbd.getResourceDescription(), beanName,                    "BeanPostProcessor before instantiation of bean failed", ex);     }
//创建bean

      Object beanInstance = doCreateBean(beanName, mbd, args);      if (logger.isDebugEnabled()) {           logger.debug("Finished creating instance of bean '"   beanName   "'");     }        return beanInstance;   }

再查看doCreateBean()方法:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {       // Instantiate the bean.     BeanWrapper instanceWrapper = null;        if (mbd.isSingleton()) {//假设是单例的。则移除缓存中的同name bean          instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);     }        if (instanceWrapper == null) {//创建Bean          instanceWrapper = createBeanInstance(beanName, mbd, args);       }        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);     Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
      // Allow post-processors to modify the merged bean definition.       synchronized (mbd.postProcessingLock) {          if (!mbd.postProcessed) {                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);              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.初始化bean。通常在此处发生依赖注入     Object exposedObject = bean;        try {          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;  }

与依靠注入相关的四个法子:createBeanInstance和populateBean。

 

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);         }        }
      //构造函数实例化       Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);     if (ctors != null ||             mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||              mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {          return autowireConstructor(beanName, mbd, ctors, args);        }
      // 使用无參构造函数      return instantiateBean(beanName, mbd); }

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
//使用CGLIB对bean进行实例化。
      try {          Object beanInstance;          final BeanFactory parent = this;           if (System.getSecurityManager() != null) {               beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {                    @Override                    public Object run() {                     return getInstantiationStrategy().instantiate(mbd, beanName, parent);                  }                }, getAccessControlContext());         }            else {             beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);          }            BeanWrapper bw = new BeanWrapperImpl(beanInstance);         initBeanWrapper(bw);           return bw;     }        catch (Throwable ex) {         throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);        }    }

在Bean实例化后,就是连锁的看重关系。

    ​正视注入的发出是在BeanWrapper的setPropertyValues中完成。详细完毕是在BeanWrapper的子类,BeanWrapperImpl中贯彻。

如上正是百分百IoC进度创设Bean的全部思路。与书中比较,省略了一部分代码。

    经过大家作证是正确的。

BookFactory实现了FactoryBean,则当使用getBean("book")时,再次回到FactoryBean#getObject()方法再次来到的目的,即FactoryBean#getObject()代理了getBean()方法:

回顾介绍

1,在Spring中,SpringIoC提供了一个至关心重视要的JavaBean容器。通过IoC方式管理依赖关系。并透过依赖注入和AOP切面加强了为JavaBean那样子的POJO提供事务处理,生命周期管理等职能。

2,Spring IoC的宏图中,重要归纳七个主导的容器类别:

    -1,BeanFactory体系。该种类完毕了容器的基本功效。

    -2。ApplicationContext应用上下文。

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object beanInstance;
            final BeanFactory parent = this;
            if (System.getSecurityManager() != null) {
                beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
                    public Object run() {
                        return getInstantiationStrategy().instantiate(mbd, beanName, parent);
                    }
                }, getAccessControlContext());
            }
            else {
                beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
            }
            BeanWrapper bw = new BeanWrapperImpl(beanInstance);
            initBeanWrapper(bw);
            return bw;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
        }
    }

singletonFactories<BeanName, BeanFactory> .get(beanName):调用对应单例创制工厂getObject()返回Bean对象。

总结

    ​BeanDefinition的定位。对IoC容器来讲,它为管理POJO间接的关联提供了帮手,但也要依赖Spring的定义准绳提供Bean定义音信。在Bean定义方面,Spring为用户提供了要命大的狡滑。在初步化进度中,首先必须定义到那些有效地Bean定义新闻。这里Spring使用Resource接口来归并那么些音讯。而牢固由ResourceLoader完结。

    ​容器的伊始化。容器的发轫化进程是在refresh()方法中甘休的。那个refresh()相当于器皿的初始化函数。在起首化中,比較主要的正是对Bean音信的加载和注冊作用。

  大家对Bean的实例化和天性解析并拓展类型转变,举例正视注入。

假若要获得BookFactoryBean对象,则要求使用前缀“&”,使用如下:

ApplicationContext的运用场景

   1。 ApplicationContext在BeanFactory的底子上增加了相当多新的表征:

    -1。协助不相同的消息源。ApplicationContext增添了MessageSource接口,那些为国际化提供劳动。

    -2,訪问资源。对ResourceLoader和Resource的支撑。能够从分歧的地点获得到财富。

    -3。帮助选拔事件。

承袭ApplicationEventPublisher,进而引进的事件机制。

与Bean的生命周期结合,方便管理Bean。

    -4,在ApplicationContext增多叠合服务。

    2,ApplicationContext设计原理,以FileSystemApplicationContext为例。

public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)           throws BeansException {
       super(parent);       setConfigLocations(configLocations);        if (refresh) {          refresh();        } }

    在实例化该利用中,调用了AbstractApplicationContext的refresh方法。该情势是IoC容器运转的重大措施。

    另三个根本措施是:

  @Override protected Resource getResourceByPath(String path) {      if (path != null && path.startsWith("/")) {           path = path.substring(1);       }     return new FileSystemResource(path);    }

该办法通过FileSystemResource获取财富路线。

      

package org.springframework.beans.factory;

/**
* Interface to be implemented by objects used within a {@link BeanFactory}
* which are themselves factories. If a bean implements this interface,
* it is used as a factory for an object to expose, not directly as a bean
* instance that will be exposed itself.
*/
public interface FactoryBean<T> {

  /**
    * Return an instance (possibly shared or independent) of the object
    * managed by this factory.
    */
  T getObject() throws Exception;

  /**
    * Return the type of object that this FactoryBean creates,
    * or {@code null} if not known in advance.  
    */
  Class<?> getObjectType();

  /**
    * Is the object managed by this factory a singleton? That is,
    * will {@link #getObject()} always return the same object
    * (a reference that can be cached)?
    * 单例对象会放在Spring单例缓存池中
    */
  boolean isSingleton();

}

      (8)获取BeanWrapper里已经实例好的Bean,然后嵌入缓存,那样下一次一度有了,就不要在创设。

        -->earlySingletonObjects.put(beanName, singletonObject)存储获取的Bean实例。

图片 4

Spring起始化bean的时候,会率先起首化那几个bean所对应的依赖。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // CONVERSION_SERVICE_BEAN_NAME为转换服务(ConversionService)  
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        // Allow for caching all bean definition metadata, not expecting further changes.
        beanFactory.freezeConfiguration();

        // 对bean进行实例化
        beanFactory.preInstantiateSingletons();
    }
Book book = ctx.getBean("book");

   <bean id="test瑟维斯" class="cn.test.service.impl.TestServiceImpl" > <property name="testService2" ref="testService2"></property></bean>,在性质注入时,类型调换明确是引用类型。大家来追踪一下代码,如图所示:

 

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;
                       ///使用BeanPostProcessor处理器处理属性值  
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }
        //对属性的注入
        applyPropertyValues(beanName, mbd, bw, pvs);
    }   
  1. Aware:注入相应能源。
  2. PostProcessor:预置管理。
  3. Init管理:配置init-method或许三番五次InitializingBean#afterPropertiesSet()方法。afterPropertiesSet先于init-method。

  

earlySingletonObjects<BeanName, BeanInstance> .get(beanName):拍卖循环引用正视质量评定。

     今后思绪就比较清晰了,接下去大家来分析具体贯彻创造Bean实例化的类。

        ↓↓

   图片 5

缓存中保存的是bean的庐山真面目状态,须求开始展览bean的实例化操作。

    是走援用类型路径,那时会调用genBean(),实行对引用类举行实例化,那都以交由IOC容器实现的,如图所示:

  1. if singleton,清除缓存。
  2. 实例化Bean(createBeanInstance),BeanDefinition=》BeanWrapper。
    运用工厂方法创制:RootBeanDefinition存在factoryMethodName,或配备了factory-method=》instantiateUsingFactoryMethod()
            ↓↓
            ↓↓<不存在>
            ↓↓
    听大人说参数选取相应的构造函数开头化
            ↓↓
            ↓↓<不存在>
            ↓↓
    默许构造函数实例化。
  3. MergeBeanDefinitionPostProcessor:合并后甩卖,注解管理地点。
  4. 借助于管理。
  5. 属性填充。
  6. 巡回信赖检查,Spring管理循环重视只对singleton有效。
  7. 注册DisposableBean,处理destroy-method。
  8. 完了成立。

preInstantiateSingletons由对bean实行实例化由子类DefaultListableBeanFactory来兑现的。源代码:

单例bean在Spring容器里只会创建壹遍,后续创制时会首先从缓存中得到,尝试加载,不成事则从singletonFatories中加载。当存在循环重视的时候,依靠Spring的加载bean原则,下贰个bean须要依赖上二个bean的时候从来行使ObjectFactory。

       

单例Bean(singleton)获取步骤:

        图片 6

Bean创建:

  

 

    (1)对品质实行巡回,然后拿走属性值

        ↓↓

        (4)判别Bean注重对象具有的名号,假诺有的话,获取信赖对象的称号,然后循环getBean();

singletonObjects<BeanName, BeanInstance>.get(beanName):Map单例缓存获取。synchronized(this.singletonObjects),全局变量同步。

   SpringMVC最基本的IOC的决定反转,动态的向有些对象提供它所急需的别样对象,比方:对象A时,要求对象B时,那时不像在此之前我们后面要在A对象里实例化B对象,这时B对象的实例化由IOC容器会主动创设一个指标B然后注入到指标A里,提供使用。大家项目开垦中,最平日接纳,那怎么落到实处实例Bean并借助注入呢?大家明日带着这几个难点来由此SpringMVC源代码实行长远的分析。那篇介绍不对评释实例化和注入实行教学,那几个位于前面在介绍。

 

     

Bean初始化:Aware方法,Post处理,Init处理。

   大家对那几个主意在计算一下:

工厂方法配置bean如下:

        (5)检查Bean的效能域,Scope 功能域、原型作用域、Request等,来实例化Bean ,是由FactoryBean是开创成立对象的工厂Bean,通过调用那么些指标                        的 getObject 方法就会获得用户自定义发生的对象,进而为 Spring 提供了很好的扩大性。Spring 获取 FactoryBean 自己的靶子是在前边加上 & 来形成                  的。

        ↓↓

本文由ca88发布,转载请注明来源

关键词: java springmvc mvc bean