我们知道,在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方法。