Spring Bean的生命同期Debug
摘要
Spring在启动的时候注册一个完整的Bean到容器的过程大致的分为注册、实例化、初始化、销毁!精妙的地方是在每个阶段Spring都对外提供了接口,用于扩展Bean在每个阶段的功能!
示例
@Component
public class BeanLifeCycle implements BeanNameAware,
BeanFactoryAware, EnvironmentAware, ApplicationContextAware, ResourceLoaderAware, InitializingBean {
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【setBeanFactory】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@Override
public void setBeanName(String s) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【setBeanName】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【setApplicationContext】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@Override
public void setEnvironment(Environment environment) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【setEnvironment】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【setResourceLoader】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@PostConstruct
public void PostConstruct() {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【PostConstruct】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@PreDestroy
public void preDestroy() {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【preDestroy】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
@Override
public void afterPropertiesSet() throws Exception {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【afterPropertiesSet】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
}
@Component
public class BeanInitial implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (BeanLifeCycle.class.getSimpleName().equalsIgnoreCase(beanName)) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【postProcessBeforeInitialization】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (BeanLifeCycle.class.getSimpleName().equalsIgnoreCase(beanName)) {
final StackTraceElement stackTraceElement = Thread.currentThread().getStackTrace()[2];
System.out.println("Method:【postProcessAfterInitialization】" + "CallerClass:" + stackTraceElement.getClassName() + "#" + stackTraceElement.getMethodName());
}
return bean;
}
}
输出分析
Method:【setBeanName】CallerClass:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
Method:【setBeanFactory】CallerClass:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
Method:【setEnvironment】CallerClass:org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces
Method:【setResourceLoader】CallerClass:org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces
Method:【setApplicationContext】CallerClass:org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces
Method:【postProcessBeforeInitialization】CallerClass:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
Method:【PostConstruct】CallerClass:sun.reflect.NativeMethodAccessorImpl#invoke0
Method:【afterPropertiesSet】CallerClass:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
Method:【postProcessAfterInitialization】CallerClass:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
2021-09-03 16:22:06.551 INFO 81022 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2021-09-03 16:22:06.651 INFO 81022 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path ''
2021-09-03 16:22:06.665 INFO 81022 --- [ restartedMain] com.boot.boot.BootApplication : Started BootApplication in 1.876 seconds (JVM running for 2.619)
Method:【preDestroy】CallerClass:sun.reflect.NativeMethodAccessorImpl#invoke0
打印出了函数调用Stack,通过打印出的日志,结合着源码看会更清楚一些!
本文来自博客园,作者:乌托拉赛文,转载请注明原文链接:https://www.cnblogs.com/m78-seven/articles/15223701.html