• Spring IOC(三)依赖注入


    本系列目录:

    Spring IOC(一)概览

    Spring IOC(二)容器初始化

    Spring IOC(三)依赖注入

    Spring IOC(四)总结

    目录

    1.AbstractBeanFactory设计类图

    2.模拟容器获取Bean,源码剖析

    3.总结

    =====正文分割线=============

    前面一章讲解的高级容器ApplicationContext的接口设计和ClassPathXmlApplicationContext实现类从xml文件中载入bean的过程,其它实现类大同小异。

    光生成Bean还不够,还得在需要使用的地方获取到才能使用,即依赖注入。主要涉及源码AbstractBeanFactory。本章先分析AbstractBeanFactory类的类图,再结合例子看源码如何获取bean.

    一、核心类图

     

    如上图,核心类AbstractBeanFactory,相关接口描述:

    AliasRegistry接口:别名注册接口。声明了别名的注册、移除、判断是否别名、获取接口。

    SimpleAliasRegistry类:简单别名注册器,实现了AliasRegistry接口。维护了一个ConcurrentHashMap,key是别名,value是bean name。

    SingletonBeanRegistry接口:单例bean注册接口。声明了对单例bean的对象获取、名称获取、注册、判断包含、计数。获取单例互斥量对象。

    DefaultSingletonBeanRegistry类:默认单例Bean注册器,继承自SimpleAliasRegistry。同时实现了SingletonBeanRegistry接口。即同时具有别名注册+单例bean注册的功能。并且拓展了对单例的一系列操作。拓展维护了11个集合用以存储各种业务数据。(例如缓存了单例对象、单例工厂、注册过的单例、正在创建中的单例)

    FactoryBeanRegistrySupport类:工厂bean注册支持类,继承自DefaultSingletonBeanRegistry。拓展维护一个ConcurrentHashMap<String, Object>,key是工厂bean名称,value是bean对象,作为工厂bean创建的bean对象缓存使用。

    ConfigurableBeanFactory接口:可配置bean工厂接口。继承自HierarchicalBeanFactory、SingletonBeanRegistry接口。拓展维护了父类工厂、工厂的类加载器、值解析器、类型转换器、bean后处理器、注册scope、bean表达式解析器等等。

    AbstractBeanFactory类继承自FactoryBeanRegistrySupport,实现了ConfigurableBeanFactory接口。拓展了containsBeanDefinition、getBeanDefinition、createBean3个抽象方法,供子类实现。

    AutowireCapableBeanFactory接口:自动装备bean工厂接口。声明了bean的创建、自动装配、配置、初始化bean、初始化前后bean处理器、销毁bean。

    AbstractAutowireCapableBeanFactory类:继承自AbstractBeanFactory,实现了AutowireCapableBeanFactory接口。即支持了bean生命周期的各种细粒度的实现。

    二、模拟容器获取Bean,源码剖析

    1     public static void main(String[] args) {
    2         //源码入口,从类路径下读取xml
    3         ApplicationContext ac1 = new ClassPathXmlApplicationContext("aop.xml");
    4         Dao dao = (Dao)ac1.getBean("daoImpl",Dao.class);//根据名称和class获取Bean
    5         dao.select();//执行Bean实例方法    
          }

     debug运行,F6单步跳过,F5进入方法,发现最终执行的AbstractBeanFactorydoGetBean方法,源码如下:

      1 protected <T> T doGetBean(
      2             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      3             throws BeansException {
      4         //获取规范的bean name
      5         final String beanName = transformedBeanName(name);
      6         Object bean;
      7 
      8         // 1.从缓存中获取bean实例
      9         Object sharedInstance = getSingleton(beanName);
    //能获取到
    10 if (sharedInstance != null && args == null) { 11 if (logger.isDebugEnabled()) { 12 if (isSingletonCurrentlyInCreation(beanName)) {//debug循环引用 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 }
    //bean实例--》bean
    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 //2.从父容器中直接获取bean. 31 BeanFactory parentBeanFactory = getParentBeanFactory();
    //当前容器的父容器存在,且当前容器中不存在指名的Bean
    32 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { 33 // 解析Bean的原始名. 34 String nameToLookup = originalBeanName(name); 35 if (args != null) { 36 //委派给父类容器查找,根据指定的名称和显示参数. 37 return (T) parentBeanFactory.getBean(nameToLookup, args); 38 } 39 else { 40 // 委派给父类容器查找,根据指定的名称和类型. 41 return parentBeanFactory.getBean(nameToLookup, requiredType); 42 } 43 } 44 //创建的Bean是否需要进行验证,一般不需要 45 if (!typeCheckOnly) {
    //添加进已创建set
    46 markBeanAsCreated(beanName); 47 } 48 49 try {
    //根据Bean的名字获取BeanDefinition
    50 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 51 checkMergedBeanDefinition(mbd, beanName, args); 52 53 // 初始化依赖bean 54 String[] dependsOn = mbd.getDependsOn(); 55 if (dependsOn != null) { 56 for (String dep : dependsOn) { 57 if (isDependent(beanName, dep)) { 58 throw new BeanCreationException(mbd.getResourceDescription(), beanName, 59 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); 60 } 61 registerDependentBean(dep, beanName); 62 getBean(dep);//递归 63 } 64 } 65 66 // 3.单例模式获取bean 67 if (mbd.isSingleton()) {
                  // 使用一个内部匿名类,创建Bean实例对象,并且注册对所依赖的对象
    68 sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 69 @Override 70 public Object getObject() throws BeansException { 71 try {
                          // 创建一个指定Bean实例对象,如果有父级继承,则合并
    72 return createBean(beanName, mbd, args); 73 } 74 catch (BeansException ex) { 75 // Explicitly remove instance from singleton cache: It might have been put there 76 // eagerly by the creation process, to allow for circular reference resolution. 77 // Also remove any beans that received a temporary reference to the bean. 78 destroySingleton(beanName); 79 throw ex; 80 } 81 } 82 });
                   // 获取给定Bean实例对象FactoryBean-》bean
    83 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 84 } 85 //4.原型模式获取bean 86 else if (mbd.isPrototype()) { 87 // 每次创建新对象实例 88 Object prototypeInstance = null; 89 try {
                     // 回调方法,注册原型对象
    90 beforePrototypeCreation(beanName);
    // 创建指定Bean对象实例
    91 prototypeInstance = createBean(beanName, mbd, args); 92 } 93 finally {
                      // 回调方法,Bean无法再次创建
    94 afterPrototypeCreation(beanName); 95 }
    // 获取给定Bean实例对象FactoryBean-》bean
    96 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 97 } 98 //5.从scope中获取bean 99 else { 100 String scopeName = mbd.getScope(); 101 final Scope scope = this.scopes.get(scopeName); 102 if (scope == null) { 103 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'"); 104 } 105 try {
    // 从scope中获取bean
    106 Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 107 @Override 108 public Object getObject() throws BeansException { 109 beforePrototypeCreation(beanName); 110 try { 111 return createBean(beanName, mbd, args); 112 } 113 finally { 114 afterPrototypeCreation(beanName); 115 } 116 } 117 }); 118 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); 119 } 120 catch (IllegalStateException ex) { 121 throw new BeanCreationException(beanName, 122 "Scope '" + scopeName + "' is not active for the current thread; consider " + 123 "defining a scoped proxy for this bean if you intend to refer to it from a singleton", 124 ex); 125 } 126 } 127 } 128 catch (BeansException ex) { 129 cleanupAfterBeanCreationFailure(beanName); 130 throw ex; 131 } 132 } 133 134 // 对创建的Bean进行类型检查,如果没有问题,就返回这个新建的Bean,这个Bean已经包含了依赖关系. 135 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { 136 try { 137 return getTypeConverter().convertIfNecessary(bean, requiredType); 138 } 139 catch (TypeMismatchException ex) { 140 if (logger.isDebugEnabled()) { 141 logger.debug("Failed to convert bean '" + name + "' to required type '" + 142 ClassUtils.getQualifiedName(requiredType) + "'", ex); 143 } 144 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); 145 } 146 } 147 return (T) bean; 148 }

    AbstractBeanFactory的doGetBean方法获取bean有5种方法如下:

    1. 从缓存中获取bean
    2. 父容器中直接获取bean
    3. 单例模式获取bean
    4. 原型模式获取bean
    5. 从scope中获取bean

    其中,除了从父容器中直接获取bean外,其它4种方法都包含2个步骤:createBeanbean实例的创建和初始化、getObjectForBeanInstance从bean实例中获取bean对象下面详细追一下源码。

    1.bean实例的创建和初始化

    createBean(beanName, mbd, args),这就是核心方法了。AbstractBeanFactory的createBean只是一个声明,在子类AbstractAutowireCapableBeanFactory中覆盖实现,源码如下:

     1 @Override
     2     protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
     3         if (logger.isDebugEnabled()) {
     4             logger.debug("Creating instance of bean '" + beanName + "'");
     5         }
     6         RootBeanDefinition mbdToUse = mbd;
     7 
     8         // 确保bean的类解析完毕,如果是动态解析类型,不会存储合并到bean定义中。克隆一份bean定义。
    11         Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    12         if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
    13             mbdToUse = new RootBeanDefinition(mbd);
    14             mbdToUse.setBeanClass(resolvedClass);
    15         }
    16 
    17         // Prepare method overrides.
    18         try {
    19             mbdToUse.prepareMethodOverrides();
    20         }
    21         catch (BeanDefinitionValidationException ex) {
    22             throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
    23                     beanName, "Validation of method overrides failed", ex);
    24         }
    25 
    26         try {
    27             // 如果Bean配置了实例化前处理器,则返回一个Bean对象
    28             Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    29             if (bean != null) {
    30                 return bean;
    31             }
    32         }
    33         catch (Throwable ex) {
    34             throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
    35                     "BeanPostProcessor before instantiation of bean failed", ex);
    36         }
    37         // 核心方法
    38         Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    39         if (logger.isDebugEnabled()) {
    40             logger.debug("Finished creating instance of bean '" + beanName + "'");
    41         }
    42         return beanInstance;
    43     }

    进入doCreateBean

      1 /**
      2      * Actually create the specified bean. Pre-creation processing has already happened
      3      * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
      4      * <p>Differentiates between default bean instantiation, use of a
      5      * factory method, and autowiring a constructor.
      6      * @param beanName the name of the bean
      7      * @param mbd the merged bean definition for the bean
      8      * @param args explicit arguments to use for constructor or factory method invocation
      9      * @return a new instance of the bean
     10      * @throws BeanCreationException if the bean could not be created
     11      * @see #instantiateBean
     12      * @see #instantiateUsingFactoryMethod
     13      * @see #autowireConstructor
     14      */
     15     protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
     16             throws BeanCreationException {
     17 
     18         // Instantiate the bean.
     19         BeanWrapper instanceWrapper = null;
     20         if (mbd.isSingleton()) {// 单例模式,清除缓存bean
     21             instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
     22         }
     23         if (instanceWrapper == null) {
     24             instanceWrapper = createBeanInstance(beanName, mbd, args);
     25         }
     26         final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
     27         Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
     28         mbd.resolvedTargetType = beanType;
     29 
     30         // 允许处理器修改合并bean定义
     31         synchronized (mbd.postProcessingLock) {
     32             if (!mbd.postProcessed) {
     33                 try {
     34                     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
     35                 }
     36                 catch (Throwable ex) {
     37                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     38                             "Post-processing of merged bean definition failed", ex);
     39                 }
     40                 mbd.postProcessed = true;
     41             }
     42         }
     43 
     44         // 如果是单例模式,且允许循环引用,且当前单列正在创建中,则返回之前的bean引用
     46         boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
     47                 isSingletonCurrentlyInCreation(beanName));
     48         if (earlySingletonExposure) {
     49             if (logger.isDebugEnabled()) {
     50                 logger.debug("Eagerly caching bean '" + beanName +
     51                         "' to allow for resolving potential circular references");
     52             }
     53             addSingletonFactory(beanName, new ObjectFactory<Object>() {
     54                 @Override
     55                 public Object getObject() throws BeansException {
     56                     return getEarlyBeanReference(beanName, mbd, bean);
     57                 }
     58             });
     59         }
     60 
     61         // 初始化(依赖注入)
     62         Object exposedObject = bean;
     63         try {
     64             populateBean(beanName, mbd, instanceWrapper);// 数据填充进实例
     65             if (exposedObject != null) {
     66                 exposedObject = initializeBean(beanName, exposedObject, mbd);
     67             }
     68         }
     69         catch (Throwable ex) {
     70             if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
     71                 throw (BeanCreationException) ex;
     72             }
     73             else {
     74                 throw new BeanCreationException(
     75                         mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
     76             }
     77         }
     78         // 早期已注册的单例bean生成方案,有依赖的注入依赖,无依赖的直接返回引用
     79         if (earlySingletonExposure) {
     80             Object earlySingletonReference = getSingleton(beanName, false);
     81             if (earlySingletonReference != null) {
     82                 if (exposedObject == bean) {
     83                     exposedObject = earlySingletonReference;
     84                 }
     85                 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
     86                     String[] dependentBeans = getDependentBeans(beanName);
     87                     Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
     88                     for (String dependentBean : dependentBeans) {
     89                         if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
     90                             actualDependentBeans.add(dependentBean);
     91                         }
     92                     }
     93                     if (!actualDependentBeans.isEmpty()) {
     94                         throw new BeanCurrentlyInCreationException(beanName,
     95                                 "Bean with name '" + beanName + "' has been injected into other beans [" +
     96                                 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
     97                                 "] in its raw version as part of a circular reference, but has eventually been " +
     98                                 "wrapped. This means that said other beans do not use the final version of the " +
     99                                 "bean. This is often the result of over-eager type matching - consider using " +
    100                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    101                     }
    102                 }
    103             }
    104         }
    105 
    106         // 注册完成依赖注入的Bean.(如果有销毁方法添加销毁方法等待回调)
    107         try {
    108             registerDisposableBeanIfNecessary(beanName, bean, mbd);
    109         }
    110         catch (BeanDefinitionValidationException ex) {
    111             throw new BeanCreationException(
    112                     mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    113         }
    114 
    115         return exposedObject;
    116     }

    如上图,doCreateBean方法是中重要的方法:
    1)createBeanInstance 创建bean实例对象instanceWrapper
    2)populateBean bean定义中配置的属性注入实例对象instanceWrapper
    3)initializeBean 初始化bean

    1.createBeanInstance有三种实例化方法:

    1.工厂方法

    2.容器自动装配

    3.使用构造函数实例化。

    源码如下:

     1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
     2         // Make sure bean class is actually resolved at this point.
     3         Class<?> beanClass = resolveBeanClass(mbd, beanName);
     4 
     5         if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
     6             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     7                     "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
     8         }
     9         // 1.这里使用工厂方法对Bean进行实例化
    10         if (mbd.getFactoryMethodName() != null)  {
    11             return instantiateUsingFactoryMethod(beanName, mbd, args);
    12         }
    13 
    14         // 2.使用容器自动装配方法进行实例化
    15         boolean resolved = false;
    16         boolean autowireNecessary = false;
    17         if (args == null) {
    18             synchronized (mbd.constructorArgumentLock) {
    19                 if (mbd.resolvedConstructorOrFactoryMethod != null) {
    20                     resolved = true;
    21                     autowireNecessary = mbd.constructorArgumentsResolved;
    22                 }
    23             }
    24         }
    25         if (resolved) {
    26             if (autowireNecessary) {
    27                 return autowireConstructor(beanName, mbd, null, null);
    28             }
    29             else {
    30                 return instantiateBean(beanName, mbd);
    31             }
    32         }
    33 
    34         // 3.使用构造函数进行实例化
    35         Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    36         if (ctors != null ||
    37                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
    38                 mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
    39             return autowireConstructor(beanName, mbd, ctors, args);
    40         }
    41 
    42         // No special handling: simply use no-arg constructor.
    43         return instantiateBean(beanName, mbd);
    44     }

    上面的源码中instantiateBean:最终调用SimpleInstantiationStrategy.instantiate方法来生成Bean对象实例,它提供了两种方式

    1.BeanUtils,是jvm的反射机制

    2.cglib。这里就是典型的策略模式。

    instantiate源码如下:

     1 public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
     2         // Don't override the class with CGLIB if no overrides.
     3         if (bd.getMethodOverrides().isEmpty()) {
     4             Constructor<?> constructorToUse;
     5             synchronized (bd.constructorArgumentLock) {
     6                 constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
     7                 if (constructorToUse == null) {
     8                     final Class<?> clazz = bd.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                                 @Override
    16                                 public Constructor<?> run() throws Exception {
    17                                     return clazz.getDeclaredConstructor((Class[]) null);
    18                                 }
    19                             });
    20                         }
    21                         else {
    22                             constructorToUse =    clazz.getDeclaredConstructor((Class[]) null);
    23                         }
    24                         bd.resolvedConstructorOrFactoryMethod = constructorToUse;
    25                     }
    26                     catch (Throwable ex) {
    27                         throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    28                     }
    29                 }
    30             }
    31             // 1.通过BeanUtils进行实例化,利用反射机制获取:java.lang.reflect.Constructor
    32             return BeanUtils.instantiateClass(constructorToUse);
    33         }
    34         else {
    35             // 2.使用CGLIB来实例化对象
    36             return instantiateWithMethodInjection(bd, beanName, owner);
    37         }
    38     }

    2.populateBean:属性依赖注入方法

     1 protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
     2         PropertyValues pvs = mbd.getPropertyValues();
     3 
     4         if (bw == null) {
     5             if (!pvs.isEmpty()) {
     6                 throw new BeanCreationException(
     7                         mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
     8             }
     9             else {
    10                 // Skip property population phase for null instance.
    11                 return;
    12             }
    13         }
    14 
    15         // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    16         // state of the bean before properties are set. This can be used, for example,
    17         // to support styles of field injection.
    18         boolean continueWithPropertyPopulation = true;
    19 
    20         if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    21             for (BeanPostProcessor bp : getBeanPostProcessors()) {
    22                 if (bp instanceof InstantiationAwareBeanPostProcessor) {
    23                     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    24                     if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    25                         continueWithPropertyPopulation = false;
    26                         break;
    27                     }
    28                 }
    29             }
    30         }
    31 
    32         if (!continueWithPropertyPopulation) {
    33             return;
    34         }
    35         // 开始进行依赖注入过程,先处理autowire的注入:名字+类型注入
    36         if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
    37                 mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
    38             MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
    39 
    40             // 根据Bean的名字自动装配注入
    41             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
    42                 autowireByName(beanName, mbd, bw, newPvs);
    43             }
    44 
    45             // 根据Bean的类型自动装配注入
    46             if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
    47                 autowireByType(beanName, mbd, bw, newPvs);
    48             }
    49 
    50             pvs = newPvs;
    51         }
    52 
    53         boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    54         boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    55         // 有实例化bean处理器/需要依赖检查
    56         if (hasInstAwareBpps || needsDepCheck) {
    57             PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    58             if (hasInstAwareBpps) {// 实例化bean处理器
    59                 for (BeanPostProcessor bp : getBeanPostProcessors()) {
    60                     if (bp instanceof InstantiationAwareBeanPostProcessor) {
    61                         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    62                         pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    63                         if (pvs == null) {
    64                             return;
    65                         }
    66                     }
    67                 }
    68             }
    69             if (needsDepCheck) {// 依赖检查
    70                 checkDependencies(beanName, mbd, filteredPds, pvs);
    71             }
    72         }
    73         // 对属性进行依赖注入
    74         applyPropertyValues(beanName, mbd, bw, pvs);
    75     }

    最终追踪到applyPropertyValues方法,源码如下:

     1 protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
     2         if (pvs == null || pvs.isEmpty()) {
     3             return;
     4         }
     5 
     6         MutablePropertyValues mpvs = null;
     7         List<PropertyValue> original;
     8 
     9         if (System.getSecurityManager() != null) {
    10             if (bw instanceof BeanWrapperImpl) {
    11                 ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());// 设置安全上下文,JDK安全机制
    12             }
    13         }
    14 
    15         if (pvs instanceof MutablePropertyValues) {
    16             mpvs = (MutablePropertyValues) pvs;
    17             if (mpvs.isConverted()) {
    18                 // Shortcut: use the pre-converted values as-is.
    19                 try {
    20                     bw.setPropertyValues(mpvs);// 为实例化对象设置属性值
    21                     return;
    22                 }
    23                 catch (BeansException ex) {
    24                     throw new BeanCreationException(
    25                             mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    26                 }
    27             }
    28             original = mpvs.getPropertyValueList();
    29         }
    30         else {
    31             original = Arrays.asList(pvs.getPropertyValues());
    32         }
    33 
    34         TypeConverter converter = getCustomTypeConverter();
    35         if (converter == null) {
    36             converter = bw;
    37         }
    38         BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
    39 
    40         // Create a deep copy, resolving any references for values.
    41         List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
    42         boolean resolveNecessary = false;
    43         for (PropertyValue pv : original) {
    44             if (pv.isConverted()) {
    45                 deepCopy.add(pv);
    46             }
    47             else {
    48                 String propertyName = pv.getName();
    49                 Object originalValue = pv.getValue();
    50                 Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
    51                 Object convertedValue = resolvedValue;
    52                 boolean convertible = bw.isWritableProperty(propertyName) &&
    53                         !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
    54                 if (convertible) {
    55                     convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
    56                 }
    57                 // Possibly store converted value in merged bean definition,
    58                 // in order to avoid re-conversion for every created bean instance.
    59                 if (resolvedValue == originalValue) {
    60                     if (convertible) {
    61                         pv.setConvertedValue(convertedValue);
    62                     }
    63                     deepCopy.add(pv);
    64                 }
    65                 else if (convertible && originalValue instanceof TypedStringValue &&
    66                         !((TypedStringValue) originalValue).isDynamic() &&
    67                         !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
    68                     pv.setConvertedValue(convertedValue);
    69                     deepCopy.add(pv);
    70                 }
    71                 else {
    72                     resolveNecessary = true;
    73                     deepCopy.add(new PropertyValue(pv, convertedValue));
    74                 }
    75             }
    76         }
    77         if (mpvs != null && !resolveNecessary) {
    78             mpvs.setConverted();
    79         }
    80 
    81         // 依赖注入属性值
    82         try {
    83             bw.setPropertyValues(new MutablePropertyValues(deepCopy));
    84         }
    85         catch (BeansException ex) {
    86             throw new BeanCreationException(
    87                     mbd.getResourceDescription(), beanName, "Error setting property values", ex);
    88         }
    89     }

    setPropertyValues该方法:AbstractPropertyAccessor实现类注入依赖的属性。

    3.初始化initializeBean

     1 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
     2         if (System.getSecurityManager() != null) {
     3             AccessController.doPrivileged(new PrivilegedAction<Object>() {
     4                 @Override
     5                 public Object run() {
     6                     invokeAwareMethods(beanName, bean);
     7                     return null;
     8                 }
     9             }, getAccessControlContext());
    10         }
    11         else {
    12             invokeAwareMethods(beanName, bean);// Aware接口 设置bean name、factory、classloader13         }
    14 
    15         Object wrappedBean = bean;
    16         if (mbd == null || !mbd.isSynthetic()) {
    17             wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);// bea后处理器-初始化之前
    18         }
    19 
    20         try {
    21             invokeInitMethods(beanName, wrappedBean, mbd);// 执行初始化方法(InitializingBean
    22         }
    23         catch (Throwable ex) {
    24             throw new BeanCreationException(
    25                     (mbd != null ? mbd.getResourceDescription() : null),
    26                     beanName, "Invocation of init method failed", ex);
    27         }
    28 
    29         if (mbd == null || !mbd.isSynthetic()) {
    30             wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//bea后处理器-初始化之后
    31         }
    32         return wrappedBean;
    33     }
    34 
    35     private void invokeAwareMethods(final String beanName, final Object bean) {
    36         if (bean instanceof Aware) {
    37             if (bean instanceof BeanNameAware) {
    38                 ((BeanNameAware) bean).setBeanName(beanName);//设置bean 名称
    39             }
    40             if (bean instanceof BeanClassLoaderAware) {
    41                 ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());//设置bean类加载器
    42             }
    43             if (bean instanceof BeanFactoryAware) {
    44                 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);//设置bean 工厂
    45             }
    46         }
    47     }
    invokeInitMethods初始化方法如下:
     1 protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
     2             throws Throwable {
     3 
     4         boolean isInitializingBean = (bean instanceof InitializingBean);
     5         if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
     6             if (logger.isDebugEnabled()) {
     7                 logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
     8             }
     9             if (System.getSecurityManager() != null) {//有安全策略
    10                 try {
    11                     AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
    12                         @Override
    13                         public Object run() throws Exception {
    14                             ((InitializingBean) bean).afterPropertiesSet();//回调属性设置完后方法
    15                             return null;
    16                         }
    17                     }, getAccessControlContext());
    18                 }
    19                 catch (PrivilegedActionException pae) {
    20                     throw pae.getException();
    21                 }
    22             }
    23             else {//安全策略,直接执行
    24                 ((InitializingBean) bean).afterPropertiesSet();//回调属性设置完后方法
    
    25             }
    26         }
    27 
    28         if (mbd != null) {
    29             String initMethodName = mbd.getInitMethodName();
    30             if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
    31                     !mbd.isExternallyManagedInitMethod(initMethodName)) {
    32                 invokeCustomInitMethod(beanName, bean, mbd);
    33             }
    34         }
    35     }

    2.从bean实例中获取bean对象

    AbstractBeanFactory.getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd),源码如下:

     1 protected Object getObjectForBeanInstance(
     2             Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
     3 
     4         // Don't let calling code try to dereference the factory if the bean isn't a factory.
     5         if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
     6             throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
     7         }
     8 
     9         // 这个bean实例可能是一个普通bean或者是一个工厂Bean.
    10         // 如果bean实例不是工厂bean且这个name也不是工厂解引用(工厂本身,name以"&"开头),即已经是一个普通bean实例了直接返回即可
    12         if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
    13             return beanInstance;
    14         }
    15 
    16         Object object = null;
    17         if (mbd == null) {// bean定义为空,从缓存中获取bean
    18             object = getCachedObjectForFactoryBean(beanName);
    19         }
    20         if (object == null) {// 缓存中没有bean实例
    21             // 强转成工厂bean
    22             FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
    23             // 获取bean,单例的就缓存进concurrenthashmap
    24             if (mbd == null && containsBeanDefinition(beanName)) {
    25                 mbd = getMergedLocalBeanDefinition(beanName);
    26             }
    27             boolean synthetic = (mbd != null && mbd.isSynthetic());
    28             object = getObjectFromFactoryBean(factory, beanName, !synthetic);// 核心方法入口
    29         }
    30         return object;
    31     }

     getObjectFromFactoryBean:根据"工厂bean"、name、"是否有后置处理器"3个参数获取bean

     1 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
     2         if (factory.isSingleton() && containsSingleton(beanName)) {
     3             synchronized (getSingletonMutex()) {
     4                 Object object = this.factoryBeanObjectCache.get(beanName);
     5                 if (object == null) {
     6                     object = doGetObjectFromFactoryBean(factory, beanName);
     7                     // Only post-process and store if not put there already during getObject() call above
     8                     // (e.g. because of circular reference processing triggered by custom getBean calls)
     9                     Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
    10                     if (alreadyThere != null) {
    11                         object = alreadyThere;
    12                     }
    13                     else {
    14                         if (object != null && shouldPostProcess) {
    15                             try {
    16                                 object = postProcessObjectFromFactoryBean(object, beanName);
    17                             }
    18                             catch (Throwable ex) {
    19                                 throw new BeanCreationException(beanName,
    20                                         "Post-processing of FactoryBean's singleton object failed", ex);
    21                             }
    22                         }
    23                         this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
    24                     }
    25                 }
    26                 return (object != NULL_OBJECT ? object : null);
    27             }
    28         }
    29         else {
    30             Object object = doGetObjectFromFactoryBean(factory, beanName);
    31             if (object != null && shouldPostProcess) {
    32                 try {
    33                     object = postProcessObjectFromFactoryBean(object, beanName);
    34                 }
    35                 catch (Throwable ex) {
    36                     throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
    37                 }
    38             }
    39             return object;
    40         }
    41     }
    1.doGetObjectFromFactoryBean核心方法:根据工厂bean和名称获取bean
     1 private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
     2             throws BeanCreationException {
     3 
     4         Object object;
     5         try {// 配置了安全管理器
     6             if (System.getSecurityManager() != null) {
     7                 AccessControlContext acc = getAccessControlContext();
     8                 try {
     9                     object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
    10                         @Override
    11                         public Object run() throws Exception {
    12                                 return factory.getObject();
    13                             }
    14                         }, acc);
    15                 }
    16                 catch (PrivilegedActionException pae) {
    17                     throw pae.getException();
    18                 }
    19             }
    20             else {// 未配置安全管理器,直接获取对象
    21                 object = factory.getObject();
    22             }
    23         }
    24         catch (FactoryBeanNotInitializedException ex) {
    25             throw new BeanCurrentlyInCreationException(beanName, ex.toString());
    26         }
    27         catch (Throwable ex) {
    28             throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
    29         }
    30 
    31         // Do not accept a null value for a FactoryBean that's not fully
    32         // initialized yet: Many FactoryBeans just return null then.
    33         if (object == null && isSingletonCurrentlyInCreation(beanName)) {
    34             throw new BeanCurrentlyInCreationException(
    35                     beanName, "FactoryBean which is currently in creation returned null from getObject");
    36         }
    37         return object;
    38     }

    2.postProcessObjectFromFactoryBean:执行“初始化之后的后处理器“”

     1 protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
     2         return applyBeanPostProcessorsAfterInitialization(object, beanName);//这里是接口AutowireCapableBeanFactory定义的方法
     3     }
     4 
     5 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
     6             throws BeansException {
     7 
     8         Object result = existingBean;
     9         for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    10             result = beanProcessor.postProcessAfterInitialization(result, beanName);
    11             if (result == null) {
    12                 return result;
    13             }
    14         }
    15         return result;
    16     }

    可以看到最后调用了BeanPostProcessor接口来处理。这里不再拓展,将来会开一篇专门讲解BeanPostProcessor接口的各种实现。

    三、总结

     通过分析跟踪IOC容器依赖注入这一部分,发现主要与AbstractBeanFactoryAutowireCapableBeanFactory这两个类相关。实现了5种获取bean的方案。

    1. 从缓存中获取bean
    2. 父容器中直接获取bean
    3. 单例模式获取bean
    4. 原型模式获取bean
    5. 从scope中获取bean

    除了从父容器中直接获取bean外,其它4种方法都包含2个步骤:bean实例的创建和初始化、从bean实例中获取bean对象

  • 相关阅读:
    Android官方命令深入分析之bmgr
    Android官方命令深入分析之AVD Manager
    Android 官方命令深入分析之android
    token的设置与获取
    SpringBoot使用Redis共享用户session信息
    thymeleaf资源加载问题(从Controller跳转)
    ajax传递数组,后台更新
    BootStrap表单验证用户名重复
    hadoop3.x.x错误解决
    Hadoop安装
  • 原文地址:https://www.cnblogs.com/dennyzhangdd/p/7694250.html
Copyright © 2020-2023  润新知