Spring生態目前發展很快,Spring、Spring Boot、Spring Cloud、Spring Data等等愈來愈豐富,而且迭代也很快。
最近在找工做,面試過程當中常常有問到Spring的基礎知識,其中一個知識點就是Spring中Bean的生命週期。java
若是沒有準備,忽然問這道題有點答不上來。大概想的話就是先執行構造函數,執行一些接口方法(好比ContextAware、afterPropertiesSet),
而後執行@PostConstruct標記的方法,最後執行destroy方法(若是有的話)。面試
日常工做中:
@PostConstruct
有用到過,在類構造完成後用來執行一些自定義的初始化邏輯;
afterPropertiesSet
記得在Spring提供的類裏常常有看到;
ApplicationContextAware
接口有在工具類用到,經過定義一個static變量和方法來獲Spring的Context。spring
找到一張圖:
app
寫個Bean類來測試一下:ide
package com.cdfive.learning.spring; import ch.qos.logback.classic.Level; import ch.qos.logback.classic.LoggerContext; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; /** * Test for Spring Bean lifecycle * * @author cdfive * @date 2019-04-09 */ @Component public class BeanLifecycle implements BeanNameAware, BeanFactoryAware, ApplicationContextAware , BeanPostProcessor, InitializingBean, DisposableBean { private static int STEP = 0; private String name; private Integer age; public static void main(String[] args) { // Close the log LoggerContext loggerContext= (LoggerContext) LoggerFactory.getILoggerFactory(); ch.qos.logback.classic.Logger logger=loggerContext.getLogger("root"); logger.setLevel(Level.OFF); // Create a Spring ApplicationContext and start AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.cdfive.learning.spring"); ctx.start(); // Close the ApplicationContext ctx.close(); } public BeanLifecycle() { print("constructor"); } @PostConstruct public void postConstruct() { print("@PostConstruct"); } @PreDestroy public void preDestroy() { print("@PreDestroy"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { print("BeanFactoryAware=>setBeanFactory"); } @Override public void setBeanName(String s) { print("BeanNameAware=>setBeanName"); } @Override public void destroy() throws Exception { print("DisposableBean=>destroy"); } @Override public void afterPropertiesSet() throws Exception { print("InitializingBean=>afterPropertiesSet"); } @Override public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { print("BeanPostProcessor=>postProcessBeforeInitialization"); return null; } @Override public Object postProcessAfterInitialization(Object o, String s) throws BeansException { print("BeanPostProcessor=>postProcessAfterInitialization"); return null; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { print("ApplicationContextAware=>setApplicationContext"); } private static void print(String s) { System.out.println((++STEP) + "." + s); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
SpringBoot 2.0.5.RELEASE(即Spring 5.0.9.RELEASE)輸出以下:函數
1.constructor 2.BeanNameAware=>setBeanName 3.BeanFactoryAware=>setBeanFactory 4.ApplicationContextAware=>setApplicationContext 5.@PostConstruct 6.InitializingBean=>afterPropertiesSet 7.BeanPostProcessor=>postProcessBeforeInitialization 8.BeanPostProcessor=>postProcessAfterInitialization 9.BeanPostProcessor=>postProcessBeforeInitialization 10.BeanPostProcessor=>postProcessAfterInitialization 11.@PreDestroy 12.DisposableBean=>destroy
能夠看到,基本跟那張圖一致。工具
不過有一點很奇怪的是BeanPostProcessor的postProcessBeforeInitialization、postProcessAfterInitialization執行了2次。post
嘗試把版本下降點,改成1.5.10.RELEASE(即Spring 4.3.14.RELEASE)輸出以下:測試
1.constructor 2.BeanNameAware=>setBeanName 3.BeanFactoryAware=>setBeanFactory 4.ApplicationContextAware=>setApplicationContext 5.@PostConstruct 6.InitializingBean=>afterPropertiesSet 7.BeanPostProcessor=>postProcessBeforeInitialization 8.BeanPostProcessor=>postProcessBeforeInitialization 9.@PreDestroy 10.DisposableBean=>destroy
其中BeanPostProcessor的postProcessBeforeInitialization執行了2次,postProcessAfterInitialization沒有執行。
關於BeanPostProcessor還有待研究,暫時沒有找到這個問題的緣由.this
加深一下印象,基礎知識確實應常常溫習、總結。加油!