zoukankan      html  css  js  c++  java
  • Spring IOC 源码简单分析 04

     

    ### 准备

    ## 目标

    了解 Spring 如何初始化 bean 实例

    ##测试代码

    gordon.study.spring.ioc.IOC04_Initialization.java
    public class IOC04_Initialization {
     
        public static void main(String[] args) {
            Resource resource = new ClassPathResource("ioc/ioc04.xml");
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            BeanDefinitionReader reader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) factory);
            reader.loadBeanDefinitions(resource);
            factory.addBeanPostProcessor(new InnerBeanPostProcessor());
            InnerClass inner = factory.getBean("inner", InnerClass.class);
            System.out.println("level: " + inner.level);
            factory.destroySingleton("inner");
        }
     
        static class InnerBeanPostProcessor implements BeanPostProcessor {
     
            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                System.out.println("in postProcessBeforeInitialization()...");
                return bean;
            }
     
            @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
                System.out.println("in postProcessAfterInitialization()...");
                if (bean instanceof InnerClass) {
                    ((InnerClass) bean).level = 3;
                }
                return bean;
            }
        }
     
        static class InnerClass implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, InitializingBean, DisposableBean {
     
            private int level;
     
            public InnerClass() {
                System.out.println("construct InnerClass...");
            }
     
            @Override
            public void setBeanName(String name) {
                System.out.println("in setBeanName()..." + name);
            }
     
            @Override
            public void setBeanClassLoader(ClassLoader classLoader) {
                System.out.println("in setBeanClassLoader()..." + classLoader);
            }
     
            @Override
            public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
                System.out.println("in setBeanFactory()..." + beanFactory);
            }
     
            public void setLevel(int level) {
                System.out.println("in setLevel()...");
                this.level = level;
            }
     
            @Override
            public void afterPropertiesSet() throws Exception {
                System.out.println("in afterPropertiesSet()...");
                level = 2;
            }
     
            @Override
            public void destroy() throws Exception {
                System.out.println("in destroy()...");
            }
     
            public void init() {
                System.out.println("in init()...");
            }
     
            public void exit() {
                System.out.println("in exit()...");
            }
        }
    }
     
    ioc04.xml
    <beans ...>
        <bean id="inner" class="gordon.study.spring.ioc.IOC04_Initialization$InnerClass" init-method="init" destroy-method="exit">
            <property name="level" value="1" />
        </bean>
    </beans>
     
    执行结果
    construct InnerClass...
    in setLevel()...
    in setBeanName()...inner
    in setBeanClassLoader()...sun.misc.Launcher$AppClassLoader@73d16e93
    in setBeanFactory()...org.springframework.beans.factory.support.DefaultListableBeanFactory@2d8f65a4: defining beans [inner]; root of factory hierarchy
    in postProcessBeforeInitialization()...
    in afterPropertiesSet()...
    in init()...
    in postProcessAfterInitialization()...
    level: 3
    in destroy()...
    in exit()...
     

    ### 分析

    ## 文档描述

    BeanFactory 类的文档描述了 bean 生命周期中对外提供的扩展点。
     
    Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:
    1. BeanNameAware's setBeanName 
    2. BeanClassLoaderAware's setBeanClassLoader 
    3. BeanFactoryAware's setBeanFactory 
    4. EnvironmentAware's setEnvironment 
    5. EmbeddedValueResolverAware's setEmbeddedValueResolver 
    6. ResourceLoaderAware's setResourceLoader (only applicable when running in an application context) 
    7. ApplicationEventPublisherAware's setApplicationEventPublisher (only applicable when running in an application context) 
    8. MessageSourceAware's setMessageSource (only applicable when running in an application context) 
    9. ApplicationContextAware's setApplicationContext (only applicable when running in an application context) 
    10. ServletContextAware's setServletContext (only applicable when running in a web application context) 
    11. postProcessBeforeInitialization methods of BeanPostProcessors 
    12. InitializingBean's afterPropertiesSet 
    13. a custom init-method definition 
    14. postProcessAfterInitialization methods of BeanPostProcessors 
     
    On shutdown of a bean factory, the following lifecycle methods apply:
    1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors 
    2. DisposableBean's destroy 
    3. a custom destroy-method definition 
     

    ## 示例代码分析

    InnerClass 首先通过默认构造函数被实例化,输出 construct InnerClass...
     
    接着装配属性,调用 setLevel 方法设置 level 属性,输出 in setLevel()...
     
    然后就开始初始化 bean。通过 AbstractAutowireCapableBeanFactory initializeBean 方法。
     
     
    按照文档描述,Spring 框架先按顺序处理 BeanNameAware(1), BeanClassLoaderAware(2) 和 BeanFactoryAware(3),对应代码第1615行。
     
    接着,第1620行代码处理 BeanPostProcessors 的 beforeInitialization 扩展点(11)。遍历 List<BeanPostProcessor> beanPostProcessors,调用每个 BeanPostProcessor 的 postProcessBeforeInitialization 方法。
     
    然后,第1624行代码调用初始化方法:如果 bean 是 InitializingBean 实例,则调用 afterPropertiesSet 方法(12);如果 XML 文件中还定义了 init-method,则通过反射调用 init-method(13)。此外,Spring 框架尽力保证同一个初始化方法不会执行多次(可以尝试将 init-method 修改为 "afterPropertiesSet",看看执行结果)。
     
    最后,第1633行代码处理BeanPostProcessors 的 afterInitialization 扩展点(14)。遍历 List<BeanPostProcessor> beanPostProcessors,调用每个 BeanPostProcessorpostProcessAfterInitialization方法。
     
  • 相关阅读:
    实验10 指针2。
    作业5 指针应用1。
    实验9 指针1。
    作业4 函数应用。
    实验8 数组2。
    实验7 综合练习。
    实验6 数组1。
    实验5 函数。
    作业3 应用分支与循环结构解决问题。
    作业2 分支、循环结构。
  • 原文地址:https://www.cnblogs.com/gordonkong/p/7361886.html
Copyright © 2011-2022 走看看