`
zhoujian1982318
  • 浏览: 35393 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring Ioc 容器 创建Bean 的流程

阅读更多

1、Spring 版本 3.1

 

2、BeanFactory 创建bean 流程:

 

以 DefaultListableBeanFactory 为例说明BeanFactory 创建bean的流程。 DefaultListableBeanFactory是Spring提供的两个重要的BeanFactory的实现

 

2.1、当我们调用类似 DefaultListableBeanFactory 的getBean(...) 方法时候、 会去调用其父类AbstractAutowireCapableBeanFactory 的 createBean(...) 方法:

 

2.2、 AbstractAutowireCapableBeanFactory 的 createBean 如下:

 

protected Object createBean( final String beanName, final RootBeanDefinition mbd,

        final Object[] args) throws BeanCreationException {

     .... // 省略

      // Make sure bean class is actually resolved at this point.

      resolveBeanClass(mbd, beanName); // 2.2.1 .解析Bean的 class

      // Prepare method overrides.

     try {

        mbd.prepareMethodOverrides(); // 2.2.2 ???

     } catch (BeanDefinitionValidationException ex) {

       .... // 省略

     }

     try {

   // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.

    // 2.2.3. BeanPostProcessor扩展点 ,会回调BeanPostProcessor接口中定义的

            postProcessBeforeInstantiation 和 postProcessAfterInstantiation

     Object bean = resolveBeforeInstantiation(beanName, mbd);

     if (bean != null ) {

      return bean; // 2.2.4. 如果2.2.3处的扩展点返回的bean不为空,直接返回该bean ,后续流程不执行

     }

    } catch (Throwable ex) {

     ... // 省略

       }

    Object beanInstance = doCreateBean(beanName, mbd, args); //2.2.5. 执行创建bean实例的流程

      ... // 省略

    return beanInstance;

}

 

注意: 2.2.3、 BeanPostProcessor 扩展点(只有 InstantiationAwareBeanPostProcessor 接口的实现才会被调 用)

 

2.3、 AbstractAutowireCapableBeanFactory 的 doCreateBean方法代码如下:

 

protected Object doCreateBean ( final String beanName, final RootBeanDefinition mbd,

            final Object[] args) {

    //2.3.1、构造Bean,并返回bean 的 BeanWrapper 类

  BeanWrapper instanceWrapper = null ;

  if (mbd.isSingleton()) {

      instanceWrapper = this . factoryBeanInstanceCache .remove(beanName);

  }

  if (instanceWrapper == null ) {

      instanceWrapper = createBeanInstance(beanName, mbd, args);

  }

  final Object bean = (instanceWrapper != null ?instanceWrapper .getWrappedInstance() : null );

  Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null );

  // Allow post-processors to modify the merged bean definition.

   //2.3.2、回调 MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition接口

  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) {

      // ... 省略日志

      addSingletonFactory(beanName, new ObjectFactory() {

          public Object getObject() throws BeansException {

                  // 2.3.3、回调SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference 接口

              return getEarlyBeanReference(beanName, mbd, bean);

          }

      });

  }

  // Initialize the bean instance.

  Object exposedObject = bean;

  try {

        // 2.3.4、组装-Bean依赖

    populateBean(beanName, mbd, instanceWrapper);

    if (exposedObject != null ) {

        // 2.3. 5、初始化Bean

        exposedObject = initializeBean(beanName, exposedObject, mbd);

    }

   } catch (Throwable ex) {

      // ... 省略

  }

  if (earlySingletonExposure) {

      // ... 省略部分代码, 代码用途???

  }

  // Register bean as disposable.

 

   // 注册Bean的销毁回调

  try {

      registerDisposableBeanIfNecessary(beanName, bean, mbd);

  } catch (BeanDefinitionValidationException ex) {

      // ... 省略

  }

  return exposedObject;

}

 

2.4、 AbstractAutowireCapableBeanFactory 的 populateBean方法代码如下:

 

 

protected void populateBean(String beanName, AbstractBeanDefinition mbd,

               BeanWrapper bw) {

     PropertyValues pvs = mbd.getPropertyValues();

     if (bw == null ) {

        if (!pvs.isEmpty()) {

            // ... 省略

        } 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 ;

    }

 

       // 2.4.1 根据name或type 自动装配

    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);

              //2.4.2、执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues

        if (hasInstAwareBpps) {

                  for (BeanPostProcessor bp : getBeanPostProcessors()) {

              if (bp instanceof InstantiationAwareBeanPostProcessor) {

                  InstantiationAwareBeanPostProcessor ibp =

                                                (InstantiationAwareBeanPostProcessor) bp;

                  pvs = ibp.postProcessPropertyValues(pvs, filteredPds,

                                   bw.getWrappedInstance(), beanName);

                  if (pvs == null ) {

                      return ;

                 

              }

          }

       }

             //2.4.3、执行依赖检查

       if (needsDepCheck) {

           checkDependencies(beanName, mbd, filteredPds, pvs);

       }

            //2.4.4、应用明确的setter属性注入

            applyPropertyValues(beanName, mbd, bw, pvs);

 

}

 

注意: 2.4.2、 执行其它的依赖注入, 当Spring 配置文件中有<context:annotation-config/> 这样的标签,并且

                      使用Spring 的ApplicationContext 容器(BeanFactory 不会自动注册) 会自动注册一些内置的

                      BeanPostProcessors, 这些BeanPostProcessesors 将会在此处用到,完成一些注入工作。

                     a、AutowiredAnnotationBeanPostProcessor  执行@Autowired注入

                     b、CommonAnnotationBeanPostProcessor   执行@Resource 注入

                     c、 RequiredAnnotationBeanPostProcessor  执行@Required 的注入检查

 

2.5、 AbstractAutowireCapableBeanFactory 的 initializeBean方法代码如下:

protected Object initializeBea( final String beanName, final Object bean,

                                 RootBeanDefinition mbd) {

     //此处省略部分代码

    //2.5.1、调用Aware接口注入(BeanNameAware、BeanClassLoaderAware、BeanFactoryAware)

    invokeAwareMethods(beanName, bean);

    // 2.5.2、回调BeanPostProcessor的postProcessBeforeInitialization接口 修改Bean

    Object wrappedBean = bean;

    if (mbd == null || !mbd.isSynthetic()) {

        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

    }

 

    //2.5. 3、执行初始化回调(1、调用InitializingBean的afterPropertiesSet 2、调用自定义的init-method)

    try {

        invokeInitMethods(beanName, wrappedBean, mbd);

    } catch (Throwable ex) {

       //...异常省略

   }

   //2.5.4、回调BeanPostProcessor的postProcessAfterInitialization接口修改Bean

   if (mbd == null || !mbd.isSynthetic()) {

       wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

   }

   return wrappedBean;

}

注意: 2.5.2、 当使用Spring的ApplicationContext 容器(BeanFactory 不会自动注册) 、会自动注册一些内置的

                      BeanPostProcessors, 这些BeanPostProcessesors 将会在此处用到,完成一些初始化的工作。

          1、ApplicationContextAwareProcesso r  回调一些Aware接口 如:

                EnvironmentAware,EmbeddedValueResolverAware, ResourceLoaderAware,

                ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware

          2、 CommonAnnotationBeanPostProcessor  配置文件包含 <context:annotation-config/>时候

               会 调用有@PostConstruct Annotation 初始化的方法。

          

 

其它注意: a、由于 BeanFactory 不能自动注册BeanPostProcessor, 所以要使得BeanPostProcessor 有效,
               必须手动注册BeanPostProcessor. 调用AbstractBeanFactory 类的addBeanPostProcessor 方法.
          b、BeanFactory 会延迟加载所有的Bean,直到getbean()方法被调用是Bean才被创建, 所以配置文件中的
               lazy-init="false" 对BeanFactory 没有用处
          c、 参考: http://www.iteye.com/topic/1122859

3、ApplicationContext 创建bean 的流程:

3.1 、ApplicationContext和BeanFacotry相比,提供了更多的扩展功能, 但是其创建Bean 的流程还是通过
         BeanFactory来实现的。AbstractApplicationContext 内部使用 DefaultListableBeanFactory 类来
         得到和创建Bean. ApplicationContext的扩展功能 如: 国际化支持, 事件的发布,以及通过 
         BeanFactoryPostProcessors 和BeanPostProcessors实现的扩展功能,需要在
         ApplicationContext创建的时候做一些额外的工作, 一般ApplicationContext 在初始化的时候
         会调用 AbstractApplicationContext 的refresh 方法。

3.2  AbstractApplicationContext 的 refresh方法如下:

public void refresh() throws BeansException, IllegalStateException {

        synchronized ( this . startupShutdownMonitor ) {

            // Prepare this context for refreshing.

            prepareRefresh();

 

            // Tell the subclass to refresh the internal bean factory.

            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

 

            // Prepare the bean factory for use in this context.

                     // 3.2.1为BeanFactory 注册一些内部 BeanPostProcess 如

                     //   (ApplicationContextAwareProcessor)

            prepareBeanFactory(beanFactory);

 

            try {

                // Allows post-processing of the bean factory in context subclasses.

                postProcessBeanFactory(beanFactory);

 

                // Invoke factory processors registered as beans in the context.

               // 3.2.2 调用 在配置文件中定义的 BeanFactoryPostProcessor bean 方法的                // postProcessBeanFactory(...) 方法

                          invokeBeanFactoryPostProcessors(beanFactory);

 

                // Register bean processors that intercept bean creation.

                           // 3.2.3 注册内部的BeanPostProcessors 如有<context:annotation-config/>

                           // 这个标签将注册如下 BeanPostProcessors:

                          //AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

                          //RequiredAnnotationBeanPostProcessor 等.

               registerBeanPostProcessors(beanFactory);

 

                // Initialize message source for this context.

                            // 3.2.4 初始化ApplicationContext 内部的 MessageSource

                initMessageSource();

 

                // Initialize event multicaster for this context.

                            // 3.2.5 初始化ApplicationContext 内部的 applicationEventMulticaster

                initApplicationEventMulticaster();

 

                // Initialize other special beans in specific context subclasses.

                onRefresh();

 

                // Check for listener beans and register them.

                            // 3.2.6 注册 ApplicationListeners 在配置文件cotext 中查找ApplcationListeners

                           // 并注册他们。

                registerListeners();

 

                // Instantiate all remaining (non-lazy-init) singletons.

                            // 3.2.7 初始化配置文件 context 中的所有的singleton 并且lazy-init="false"的bean

                            // 如果scope 不是singleton, bean将不会初始化

                finishBeanFactoryInitialization(beanFactory);

 

                // Last step: publish corresponding event.

                            // 3.2.8 初始化 lifecycle processor,调用LifecycleProcessor 的onRefresh() 方法

                            // publish ContextRefreshedEvent;

                finishRefresh();

            }

 

            catch (BeansException ex) {

                // Destroy already created singletons to avoid dangling resources.

                destroyBeans();

 

                // Reset 'active' flag.

                cancelRefresh(ex);

 

                // Propagate exception to caller.

                throw ex;

            }

        }

    }

 

3.3 然后接下来流程将调用BeanFactory 创建Bean 的方法.

分享到:
评论

相关推荐

    SpringIOC容器对Bean管理的相关案例

    SpringIOC容器对Bean管理的相关案例

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 &lt;!-- 配置数据源 --&gt; &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"&gt; &lt;value&gt;org.gjt.mm.mysql.Driver ...

    spring ioc和aop原理流程图(详细)

    以下是Spring IOC容器的主要知识点: 1. **Bean的定义**:在Spring中,业务对象被称为Bean。Bean定义包含了创建和管理Bean的所有信息,如类名、属性值、依赖关系等,通常通过XML、注解或Java配置来定义。 2. **...

    Spring IOC容器实现分析.pdf 下载

    2. Bean的实例化:当需要使用某个Bean时,IOC容器会根据Bean的定义创建实例。可以是单例模式,也可以是多例模式。 3. 依赖注入:在实例化Bean的过程中,容器会根据定义的依赖关系,将其他Bean注入到当前Bean中,...

    详解Spring IOC 容器启动流程分析

    Spring IOC 容器启动流程分析 Spring IOC 容器是 Java 企业级应用程序的核心组件之一,它提供了一个统一的依赖注入机制,使得应用程序的组件之间能够松耦合。Spring IOC 容器的启动流程是整个 Spring 框架的核心...

    SpringIoC容器和Bean管理学习记录-SSM框架的学习与应用

    1.spring中bean实例化的俩种方式 2.spring中bean的各种元素如何使用 3.spring中的bean管理 4.spring中不同类型bean的作用域 ...通过我的项目,可以跟着学习SPringIoC容器和Bean管理,帮助你快速上手SSM框架

    spring IOC反射装载bean

    在Spring框架中,IOC(Inversion of Control,控制反转)是一种设计原则,它将对象的创建和管理交给了容器来处理。在这个特定的"spring IOC反射装载bean"的主题中,我们将深入探讨Spring如何通过XML配置文件来加载和...

    Spring IoC容器实现的结构分析

    在执行过程中,Spring IoC容器首先通过`BeanDefinitionReader`加载和解析bean定义,然后`BeanFactory`根据`BeanDefinition`创建bean实例。如果bean配置了自动装配,`AutowireCapableBeanFactory`会处理依赖注入。...

    springIoc实现原理

    Spring Ioc容器是整个Spring框架的基石,它负责创建、配置和管理对象。容器通过读取XML、Java注解或Java配置类等方式,获取对象的定义信息,然后根据这些信息实例化对象并进行依赖注入。 **三、依赖注入(DI,...

    手写一个SpringIoc容器

    本项目"手写一个SpringIoc容器"旨在模仿Spring的IOC(Inversion of Control,控制反转)功能,帮助开发者深入理解Spring的工作原理,提升对依赖注入(Dependency Injection)模式的认识。 在实现自定义的Spring IOC...

    Spring中IoC优点与缺点解析

    IoC(Inversion of Control)是 Spring 框架中的一种设计模式,它的主要思想是将对象的创建和管理交给容器,从而解耦合对象之间的依赖关系。今天,我们将详细解析 IoC 的优点和缺点。 优点 1. 简化对象的创建:IoC ...

    Java-Spring-SpringIoC容器-SpringIoC的学习

    Spring IoC容器通过XML配置或注解实现了对象的创建、管理和依赖注入,极大地简化了Java应用的复杂性。理解并熟练运用Spring IoC,能够帮助开发者构建更灵活、易于测试和维护的系统。在实际开发中,还可以结合@...

    Spring为IOC容器注入Bean的五种方式详解

    Spring为IOC容器注入Bean的五种方式详解 Spring 框架中,IOC(Inverse of Control,控制反转)容器是核心组件之一,用于管理 Bean 的生命周期。在 Spring 中,IOC 容器可以通过五种方式来注入 Bean,本文将对这五...

    Spring的IoC容器初始化源码解析

    `BeanFactory`是最基本的IoC容器实现,它主要负责创建和管理bean的生命周期。BeanFactory提供了一系列基础方法,例如获取bean、判断bean的存在性、判断bean是否为单例等。它是所有Spring容器的基类,为其他容器提供...

    spring在IoC容器中装配Bean详解

    在 Spring 框架中,IoC 容器是 Bean 的容器,负责创建、管理和装配 Bean。在本文中,我们将详细介绍 Spring 在 IoC 容器中装配 Bean 的过程。 一、Spring 配置概述 Spring 配置概述分为三部分:基于 XML 的配置、...

    08-IoC配置-bean的生命周期控制

    Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。 Spring IOC容器对Bean的生命周期进行管理的过程如下: 通过构造器或工厂方法创建Bean实例 为Bean的属性设置值和对其它Bean的...

    尚硅谷]_佟刚_Spring IOC 容器中 Bean 的生命周期.pdf

    1、&lt;bean&gt;标签主要用来进行Bean定义; 2、alias用于定义Bean别名的; 3、import用于导入其他配置文件的Bean定义,这是为了加载多个配置文件,当然也可以把这些配置文件构造为一个数组(new String[] {“config1.xml...

    Spring IOC容器应用实例

    在实际应用中,Spring 的 IoC 容器还提供了许多高级特性,如 Bean 的生命周期管理、AOP(面向切面编程)、事件处理、国际化支持等。例如,我们可以通过`@PostConstruct`和`@PreDestroy`注解来声明初始化和销毁方法,...

Global site tag (gtag.js) - Google Analytics