• 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方法。
     
  • 相关阅读:
    C#获取ip地址
    WPF拖动按钮实现(一)
    数据实体层
    在MSN、QQ群、论坛上提问的决窍
    控件开发及组件开发之我见
    数据结构与算法(2) vector概念介绍
    数据结构与算法(1) 数据结构概览
    Android反编译实战(5)
    自己实现CursorAdapter
    自己实现ArrayAdapter
  • 原文地址:https://www.cnblogs.com/gordonkong/p/7361886.html
Copyright © 2020-2023  润新知