生命周期
一个受 Spring 管理的 bean,生命周期主要阶段有
- 创建:根据 bean 的构造方法或者工厂方法来创建 bean 实例对象
- 依赖注入:根据 @Autowired,@Value 或其它一些手段,为 bean 的成员变量填充值、建立关系
- 初始化:回调各种 Aware 接口,调用对象的各种初始化方法
- 销毁:在容器关闭时,会销毁所有单例对象(即调用它们的销毁方法)
- prototype 对象也能够销毁,不过需要容器这边主动调用
@Component public class LifeCycleBean { private static final Logger log = LoggerFactory.getLogger(LifeCycleBean.class); public LifeCycleBean() { log.debug("构造"); } @Autowired public void autowire(@Value("${JAVA_HOME}") String home) { log.debug("依赖注入: {}", home); } @PostConstruct public void init() { log.debug("初始化"); } @PreDestroy public void destroy() { log.debug("销毁"); } }
@SpringBootApplication public class A03 { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(A03.class, args); context.close(); } }
Bean后置处理器增强
InstantiationAwareBeanPostProcessor和DestructionAwareBeanPostProcessor 分别对bean初始化和销毁之前增强
创建前的增强
- postProcessBeforeInstantiation
- 这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
- postProcessAfterInstantiation
- 这里如果返回 false 会跳过依赖注入阶段
依赖注入前的增强
- postProcessProperties
- 如 @Autowired、@Value、@Resource
初始化前后的增强
- postProcessBeforeInitialization
- 这里返回的对象会替换掉原本的 bean
- 如 @PostConstruct、@ConfigurationProperties
- postProcessAfterInitialization
- 这里返回的对象会替换掉原本的 bean
- 如代理增强
销毁之前的增强
- postProcessBeforeDestruction
- 如 @PreDestroy
收获💡
- Spring bean 生命周期各个阶段
- 模板设计模式, 指大流程已经固定好了, 通过接口回调(bean 后处理器)在一些关键点前后提供扩展
@Component public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor { private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class); @Override public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy"); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean"); return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) { log.debug("<<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段"); // return false; } return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource"); return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (beanName.equals("lifeCycleBean")) log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强"); return bean; } }
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.5.5) [INFO ] 20:35:56.881 [main] com.onethink.a03.A03 - Starting A03 using Java 17.0.5 on OneThink with PID 7572 (E:\code\java\spring_learn\show\target\classes started by moonlight in E:\code\java\spring_learn\show) [DEBUG] 20:35:56.886 [main] com.onethink.a03.A03 - Running with Spring Boot v2.5.5, Spring v5.3.10 [INFO ] 20:35:56.886 [main] com.onethink.a03.A03 - No active profile set, falling back to default profiles: default [WARN ] 20:35:57.271 [main] o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.onethink.a03]' package. Please check your configuration. [TRACE] 20:35:57.363 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] [TRACE] 20:35:57.371 [main] o.s.a.a.a.AnnotationAwareAspectJAutoProxyCreator - Did not attempt to auto-proxy infrastructure class [org.springframework.transaction.interceptor.TransactionInterceptor] [INFO ] 20:35:57.525 [main] o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) [INFO ] 20:35:57.530 [main] o.a.coyote.http11.Http11NioProtocol - Initializing ProtocolHandler ["http-nio-8080"] [INFO ] 20:35:57.530 [main] o.a.catalina.core.StandardService - Starting service [Tomcat] [INFO ] 20:35:57.530 [main] o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.53] [INFO ] 20:35:57.587 [main] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext [INFO ] 20:35:57.587 [main] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 674 ms [DEBUG] 20:35:57.614 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean [DEBUG] 20:35:57.616 [main] com.onethink.a03.LifeCycleBean - 构造 [DEBUG] 20:35:57.617 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 实例化之后执行, 这里如果返回 false 会跳过依赖注入阶段 [DEBUG] 20:35:57.617 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource [DEBUG] 20:35:57.618 [main] com.onethink.a03.LifeCycleBean - 依赖注入: D:\DevEvn\jdk\jdk-17.0.5 [DEBUG] 20:35:57.619 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties [DEBUG] 20:35:57.619 [main] com.onethink.a03.LifeCycleBean - 初始化 [DEBUG] 20:35:57.619 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强 [INFO ] 20:35:57.739 [main] o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] [INFO ] 20:35:57.798 [main] c.a.d.s.b.a.DruidDataSourceAutoConfigure - Init DruidDataSource [INFO ] 20:35:57.867 [main] c.a.druid.pool.DruidDataSource - {dataSource-1} inited [INFO ] 20:35:58.004 [main] o.a.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8080"] [INFO ] 20:35:58.031 [main] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet' [INFO ] 20:35:58.031 [main] o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet' [TRACE] 20:35:58.031 [main] o.s.web.servlet.DispatcherServlet - Detected org.springframework.web.multipart.support.StandardServletMultipartResolver@9cfc77 [TRACE] 20:35:58.031 [main] o.s.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@7418d76e [TRACE] 20:35:58.031 [main] o.s.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.theme.FixedThemeResolver@601eb4af [TRACE] 20:35:58.032 [main] o.s.web.servlet.DispatcherServlet - Detected DefaultRequestToViewNameTranslator [TRACE] 20:35:58.032 [main] o.s.web.servlet.DispatcherServlet - Detected SessionFlashMapManager [DEBUG] 20:35:58.032 [main] o.s.web.servlet.DispatcherServlet - enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data [INFO ] 20:35:58.032 [main] o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms [INFO ] 20:35:58.032 [main] o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' [INFO ] 20:35:58.038 [main] com.onethink.a03.A03 - Started A03 in 1.383 seconds (JVM running for 1.835) [INFO ] 20:35:58.069 [main] c.a.druid.pool.DruidDataSource - {dataSource-1} closing ... [INFO ] 20:35:58.070 [main] c.a.druid.pool.DruidDataSource - {dataSource-1} closed [DEBUG] 20:35:58.071 [main] c.onethink.a03.MyBeanPostProcessor - <<<<<< 销毁之前执行, 如 @PreDestroy [DEBUG] 20:35:58.071 [main] com.onethink.a03.LifeCycleBean - 销毁 Disconnected from the target VM, address: '127.0.0.1:57246', transport: 'socket'
bean后处理器的模板方法
spring 的bean后置处理器,通过模板方法的模式去增强
public class TestMethodTemplate { public static void main(String[] args) { MyBeanFactory beanFactory = new MyBeanFactory(); beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired")); beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource")); beanFactory.getBean(); } // 模板方法 Template Method Pattern static class MyBeanFactory { public Object getBean() { Object bean = new Object(); System.out.println("构造 " + bean); System.out.println("依赖注入 " + bean); // @Autowired, @Resource for (BeanPostProcessor processor : processors) { processor.inject(bean); } System.out.println("初始化 " + bean); return bean; } private List<BeanPostProcessor> processors = new ArrayList<>(); public void addBeanPostProcessor(BeanPostProcessor processor) { processors.add(processor); } } static interface BeanPostProcessor { public void inject(Object bean); // 对依赖注入阶段的扩展 } }