【Spring源码分析】Bean的生命周期
1. 前言
Spring两大核心技术IOC和AOP。而Bean的生命周期IOC技术中的一个重要内容,所以本篇文章想梳理下Spring中Bean的生命周期,加深对Bean生命周期的理解。
2. bean的扩展接口
先来看个例子:
创建一个Book类,加上@Component标注这是一个Bean,
//Book.java
@Component public class Book implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware, EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, BeanPostProcessor, InitializingBean,DisposableBean { public Book() { System.out.println("Book 正在调用Book()构造函数"); } @PostConstruct public void init() { System.out.println("Book 调用@PostConstruct注解的方法"); } @PreDestroy public void destrody() { System.out.println("Book 调用@PreDestroy注解的方法"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("Book 调用afterPropertiesSet()方法"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Book 调用setBeanFactory()方法"); } @Override public void setBeanName(String name) { System.out.println("Book 调用setBeanName()方法"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("Book 调用setBeanClassLoader()方法"); } @Override public void setEnvironment(Environment environment) { System.out.println("Book 调用setEnvironment()方法"); } @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { System.out.println("Book 调用setEmbeddedValueResolver()方法"); } @Override public void destroy() throws Exception { System.out.println("Book 调用destroy()方法"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("Book 调用setApplicationContext()方法"); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { System.out.println("Book 调用setApplicationEventPublisher()方法"); } @Override public void setMessageSource(MessageSource messageSource) { System.out.println("Book 调用setMessageSource()方法"); } @Override public void setResourceLoader(ResourceLoader resourceLoader) { System.out.println("Book 调用setResourceLoader()方法"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Book 调用postProcessBeforeInitialization()方法"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Book 调用postProcessAfterInitialization()方法"); return bean; } }
然后创建一个容器:
//main.java
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.scan("lu.ioc.lifecycle"); ac.refresh(); ac.close(); } }
运行程序,输出结果:
Book 正在调用Book()构造函数
Book 调用setBeanName()方法
Book 调用setBeanClassLoader()方法
Book 调用setBeanFactory()方法
Book 调用setEnvironment()方法
Book 调用setEmbeddedValueResolver()方法
Book 调用setResourceLoader()方法
Book 调用setApplicationEventPublisher()方法
Book 调用setMessageSource()方法
Book 调用setApplicationContext()方法
Book 调用@PostConstruct注解的方法
Book 调用afterPropertiesSet()方法
Book 调用@PreDestroy注解的方法
Book 调用destroy()方法
从以上的输出结果,可以看出Bean生命周期各接口的调用次序了。
图片来源:https://www.cnblogs.com/javazhiyin/p/10905294.html
上图的原图有个错误的地方,就是红框标注的地方,这里把错误给改正了。这里有点要说明的地方就是【调用自定义初始化方法】和【调用自定义销毁方法】,指的是Bean中被@PostConstruct和@PreDestroy修饰的方法。
细心的小伙伴可能已经发现了,为什么没有调用BeanPostProcessor接口的方法?
其实BeanPostProcessor叫后置处理器接口,是供其他Bean创建时调用的方法,比如有另外一个Bean:ShuXueBook,在该bean创建时,会调用Book的BeanPostProcessor接口实现方法。该接口的目的就是给用户修改创建Bean的扩展。
3.BeanFactory接口继承关系
上图中圆圈的代表接口,长方形代表类。
4、ApplicationContext接口继承关系
5. 源码分析
对Spring的BeanFactory和ApplicationContext接口有了初步的认识以后,下面开始源码分析。
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.scan("lu.ioc.lifecycle"); ac.refresh(); ac.close(); } }
//在lu.ioc.lifecycle包下面有Main.java 和 config包
//在lu.ioc.lifecycle.config包下面:
//Book.java
@Component
public class Book implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware,
ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware, BeanPostProcessor,
InitializingBean,DisposableBean {
public Book() {
System.out.println("Book 正在调用Book()构造函数");
}
@PostConstruct
public void init() {
System.out.println("Book 调用@PostConstruct注解的方法");
}
@PreDestroy
public void destrody() {
System.out.println("Book 调用@PreDestroy注解的方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Book 调用afterPropertiesSet()方法");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("Book 调用setBeanFactory()方法");
}
@Override
public void setBeanName(String name) {
System.out.println("Book 调用setBeanName()方法");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("Book 调用setBeanClassLoader()方法");
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("Book 调用setEnvironment()方法");
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("Book 调用setEmbeddedValueResolver()方法");
}
@Override
public void destroy() throws Exception {
System.out.println("Book 调用destroy()方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("Book 调用setApplicationContext()方法");
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("Book 调用setApplicationEventPublisher()方法");
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("Book 调用setMessageSource()方法");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("Book 调用setResourceLoader()方法");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Book 调用postProcessBeforeInitialization()方法");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Book 调用postProcessAfterInitialization()方法");
return bean;
}
}
//YuWenBook.java
@Component
public class YuWenBook implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware,
EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware,
ApplicationEventPublisherAware, MessageSourceAware, ApplicationContextAware,
InitializingBean,DisposableBean{
public YuWenBook() {
System.out.println("YuWenBook 正在调用Book()构造函数");
}
@PostConstruct
public void init() {
System.out.println("YuWenBook 调用@PostConstruct注解的方法");
}
@PreDestroy
public void destrody() {
System.out.println("YuWenBook 调用@PreDestroy注解的方法");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("YuWenBook 调用afterPropertiesSet()方法");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("YuWenBook 调用setBeanFactory()方法");
}
@Override
public void setBeanName(String name) {
System.out.println("YuWenBook 调用setBeanName()方法");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("YuWenBook 调用setBeanClassLoader()方法");
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("YuWenBook 调用setEnvironment()方法");
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("YuWenBook 调用setEmbeddedValueResolver()方法");
}
@Override
public void destroy() throws Exception {
System.out.println("YuWenBook 调用destroy()方法");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("YuWenBook 调用setApplicationContext()方法");
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("YuWenBook 调用setApplicationEventPublisher()方法");
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("YuWenBook 调用setMessageSource()方法");
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("YuWenBook 调用setResourceLoader()方法");
}
}
public class Main { public static void main(String[] args) {
//创建一个Spring容器上下文对象 AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); //扫描 lu.ioc.lifecycle包下面的class文件,识别出spring要管理的Bean,然后定义成BeanDefinition。
ac.scan("lu.ioc.lifecycle");
//这里是重点 ac.refresh(); ac.close(); } }
//ac.refresh()进入的代码如下:AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
其实生命周期方法是在 prepareBeanFactory(beanFactory) 函数中添加的,进入:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Configure the bean factory with context callbacks. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
我们来看下红色部分的代码 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
这里着重看下ApplicationContextAwareProcessor.java 这个类
class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; private final StringValueResolver embeddedValueResolver; /** * Create a new ApplicationContextAwareProcessor for the given context. */ public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory()); } @Override @Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){ return bean; } AccessControlContext acc = null; if (System.getSecurityManager() != null) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } }
看到这里大家应该知道Spring是如何提供可扩展的Aware接口了吧。