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方法。
     
  • 相关阅读:
    在手机浏览器中判断App是否已安装
    用git无法连接github的解决方法
    使用pdf.js显示pdf文件
    Javascript绝句欣赏
    HTTP Keep-Alive模式
    和浏览器并发请求数有关的一些前端技术
    Javascript标准参考教程学习记录
    [nodejs]国内npm安装nodejs modules失败的几个解决方案
    利用sfntly的sfnttool.jar提取中文字体
    Bzoj4378--Poi2015Logistyka
  • 原文地址:https://www.cnblogs.com/gordonkong/p/7361886.html
Copyright © 2011-2022 走看看