zoukankan      html  css  js  c++  java
  • Spring源码阅读(四)

    我们知道,在spring bean生命周期中,我们可以在不同阶段执行处理器或者方法,比如init-method,destroy方法,BeanPostProcessor接口等。那么这些处理器或方法的执行顺序是怎样的,让我们用实际例子来观察。

    package com.coshaho.learn.spring;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    
    import org.springframework.beans.MutablePropertyValues;
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.beans.factory.support.DefaultListableBeanFactory;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.DependsOn;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springframework.stereotype.Component;
    
    /**
     * 
     * ASpringProcessor.java Create on 2017年10月17日 下午10:06:35    
     *    
     * 类功能说明: Spring处理器执行顺序
     *
     * Copyright: Copyright(c) 2013 
     * Company: COSHAHO
     * @Version 1.0
     * @Author coshaho
     */
    @Component("springProcessor")
    @DependsOn("dependsBean")
    @ComponentScan("com.coshaho.learn.spring")
    public class ASpringProcessor implements InitializingBean, DisposableBean, BeanNameAware
    {
        @Autowired
        public BAutowiredBean autowiredBean;
        
        public ASpringProcessor()
        {
            System.out.println("SpringProcessor construct. x is " + x + ".");
        }
        
        // BeanNameAware
        public void setBeanName(String name) 
        {
            System.out.println("Call BeanNameAware setBeanName, name is " + name + ", x is " + x + ".");
        }
    
        // DisposableBean
        public void destroy() throws Exception 
        {
            System.out.println("Call DisposableBean destroy.");
        }
        
        // InitializingBean
        public void afterPropertiesSet() throws Exception 
        {
            System.out.println("Call InitializingBean afterPropertiesSet.");
        }
        
        @PostConstruct 
        public void postConstruct() 
        {
            System.out.println("Call postConstruct method.");
        }
    
        @PreDestroy
        public void preDestroy() 
        {
            System.out.println("Call preDestroy method.");
        }
        
        public void initMethod() 
        {
            System.out.println("Call manually initMethod.");
        }
    
        public void destroyMethod() 
        {
            System.out.println("Call manually destroyMethod.");
        }
        
        public void sayHello()
        {
            System.out.println("Hello, Spring.");
        }
    
        @Value("cauchy")
        private String x;
        public void setX(String x) 
        {
            this.x = x;
        }
        
        public static void main(String[] args) throws Exception 
        {
            ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
            ASpringProcessor springBean = (ASpringProcessor)context.getBean("springProcessor");
            springBean.sayHello();
            context.close();
            
            System.out.println();
            
            // 创建一个BeanFactory
            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            factory.addBeanPostProcessor(new EBeanPostProcessor());
    
            // 构造一个BeanDefinition
            AnnotatedGenericBeanDefinition beanDefinition=new AnnotatedGenericBeanDefinition(ASpringProcessor.class);
            beanDefinition.setInitMethodName("initMethod");
            beanDefinition.setDestroyMethodName("destroyMethod");
    
            // 设置这个bean的属性
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("x", "coshaho");
            beanDefinition.setPropertyValues(new MutablePropertyValues(map));
    
            // 注册BeanDefinition
            factory.registerBeanDefinition("springProcessor", beanDefinition);
    
            // 执行获取和销毁bean的方法
            factory.getBean("springProcessor");
            factory.destroySingleton("springProcessor");
        }
    }
    
    
    package com.coshaho.learn.spring;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    class EBeanPostProcessor implements BeanPostProcessor 
    {
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException 
        {
            System.out.println("MyBeanPostProcessor postProcessBeforeInitialization.");
            return bean;
        }
    
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException 
        {
            System.out.println("MyBeanPostProcessor postProcessAfterInitialization.");
            return bean;
        }
    } 
    package com.coshaho.learn.spring;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class BAutowiredBean 
    {
        public BAutowiredBean()
        {
            System.out.println("AutowiredBean construct.");
        }
    
    }
    
    package com.coshaho.learn.spring;
    
    import org.springframework.stereotype.Service;
    
    @Service("dependsBean")
    public class CDependsBean 
    {
        public CDependsBean()
        {
            System.out.println("DependsBean construct.");
        }
    
    }

    执行结果

    Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7cef4e59: startup date [Tue Oct 17 18:18:23 GMT+08:00 2017]; root of context hierarchy
    Loading XML bean definitions from class path resource [spring.xml]
    DependsBean construct.
    SpringProcessor construct. x is null.
    AutowiredBean construct.
    Call BeanNameAware setBeanName, name is springProcessor, x is cauchy.
    Call postConstruct method.
    Call InitializingBean afterPropertiesSet.
    Hello, Spring.
    Closing org.springframework.context.support.ClassPathXmlApplicationContext@7cef4e59: startup date [Tue Oct 17 18:18:23 GMT+08:00 2017]; root of context hierarchy
    Call preDestroy method.
    Call DisposableBean destroy.
    
    SpringProcessor construct. x is null.
    Call BeanNameAware setBeanName, name is springProcessor, x is coshaho.
    MyBeanPostProcessor postProcessBeforeInitialization.
    Call InitializingBean afterPropertiesSet.
    Call manually initMethod.
    MyBeanPostProcessor postProcessAfterInitialization.
    Call DisposableBean destroy.
    Call manually destroyMethod.

    可以看出来,spring bean加载顺序如下

    1. 初始化depends bean;

    2. 执行bean构造方法;

    3. 初始化依赖注入bean;

    4. 其他属性赋值;

    5. 执行BeanNameAware接口的setBeanName方法;

    6. 执行BeanPostProcessor接口postProcessBeforeInitialization方法;

    7. 执行@PostConstruct注解方法;

    8. 执行InitializingBean接口的afterPropertiesSet方法;

    9. 执行init-method方法;

    10. 执行BeanPostProcessor接口postProcessAfterInitialization方法;

    11. 执行@PreDestroy注解方法;

    12. 执行DisposableBean接口的destroy方法;

    13. 执行destroy-method方法。

  • 相关阅读:
    guava快速入门
    自旋锁解决StackOverflowError案例
    Java内存模型
    Java中sleep()与wait()区别
    wait()、notify()、notifyAll()与线程通信方式总结
    同步代码块、同步方法、锁总结
    如何把Go调用C的性能提升10倍?
    记一次虚拟化环境下Windows IO性能的解析
    win7(64bit)使用mingw64配置gtkmm
    你的深度工作,决定了你的后半生(刻意练习,最主要的竞争对手是无聊)
  • 原文地址:https://www.cnblogs.com/coshaho/p/7684370.html
Copyright © 2011-2022 走看看