Bean初始化阶段又可细分为5个阶段:
spring为我们提供了3个Aware接口,执行顺序如下:
示例代码:
package com.gaogzhen.myspring.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
/**
* Bean Aware 接口回调
* @author: Administrator
* @createTime: 2023/03/19 08:46
*/
public class AwareBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("这个Bean的类加载器是:" + classLoader);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("这个Bean的工厂对象是:" + beanFactory);
}
@Override
public void setBeanName(String name) {
System.out.println("这个Bean的名称是:" + name);
}
}
// 测试方法
@Test
public void testBeanAware() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("awareBean", BeanDefinitionBuilder.genericBeanDefinition(AwareBean.class).getBeanDefinition());
factory.getBean("awareBean");
}
输出结果:
这个Bean的名称是:awareBean
这个Bean的类加载器是:jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
这个Bean的工厂对象是:org.springframework.beans.factory.support.DefaultListableBeanFactory@67304a40: defining beans [awareBean]; root of factory hierarchy
Aware为一个标记型接口,实现相应的子接口,可以获取spring相应的底层“组件”。
在上一篇属性赋值,即AbstractAutowireCapableBeanFactory的doCreate()中populateBean()方法。getBean()执行流程来到调用Aware接口部分代码:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 省略...
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 省略...
}
继续执行initializeBean()初始化方法,代码如下:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
// 省略...
}
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware beanNameAware) {
beanNameAware.setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
beanClassLoaderAware.setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware beanFactoryAware) {
beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
在invokeAwareMethods()方法中,顺序判断bean是否实现相应接口,如果实现相应接口,执行相应的方法。
在initializeBean()方法中,执行完Aware回调之后,继续向下执行,来到Bean 初始化前阶段
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 省略...
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
// 省略...
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 省略...
}
源代码如下:
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 ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
invokeAwareInterfaces(bean);
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware environmentAware) {
environmentAware.setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware embeddedValueResolverAware) {
embeddedValueResolverAware.setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware resourceLoaderAware) {
resourceLoaderAware.setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware applicationEventPublisherAware) {
applicationEventPublisherAware.setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware messageSourceAware) {
messageSourceAware.setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationStartupAware applicationStartupAware) {
applicationStartupAware.setApplicationStartup(this.applicationContext.getApplicationStartup());
}
if (bean instanceof ApplicationContextAware applicationContextAware) {
applicationContextAware.setApplicationContext(this.applicationContext);
}
}
}
}
ApplicationContextAwareProcessor的postProcessBeforeInitialization()方法会检测,如果bean实现了以下任一Aware接口,会执行相应Aware接口的方法:
ApplicationContext
开头的,说明这个类只能在ApplicationContext
环境中使用。
CommonAnnotationBeanPostProcessor调用@PostConstruct标注的方法
CommonAnnotationBeanPostProcessor调用postProcessBeforeInitialization()方法最终调用其父类InitDestroyAnnotationBeanPostProcessor中的方法,代码如下:
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
// 省略异常处理。。。
return bean;
}
定义一个类实现上述7个接口,一个方法加上@PostStruct注解,看下输出顺序和结果,测试类如下:
package com.gaogzhen.myspring.bean;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.BeansException;
import org.springframework.context.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.metrics.ApplicationStartup;
import org.springframework.util.StringValueResolver;
/**
* 测试初始化前阶段
* @author gaogzhen
*/
public class PostProcessBeforeInitializationBean implements EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware, MessageSourceAware, ApplicationStartupAware ,ApplicationContextAware {
@PostConstruct
public void testPostProcessBeforeInitialization() {
System.out.println("postConstruct");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("applicationContext: " + applicationContext);
}
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
System.out.println("applicationEventPublisher: " + applicationEventPublisher);
}
@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
System.out.println("resolver: " + resolver);
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("environment: " + environment);
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
System.out.println("resourceLoader: " + resourceLoader);
}
@Override
public void setApplicationStartup(ApplicationStartup applicationStartup) {
System.out.println("applicationStartup: " + applicationStartup);
}
@Override
public void setMessageSource(MessageSource messageSource) {
System.out.println("messageSource: " + messageSource);
}
}
// 测试代码
public void testPostProcessBeforeInitialization() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(PostProcessBeforeInitializationBean.class);
context.refresh();
}
测试结果:
environment: StandardEnvironment {activeProfiles=[], defaultProfiles=[default], propertySources=[PropertiesPropertySource@24039137 {name='systemProperties', properties={java.specification.version=17, sun.jnu.encoding=UTF-8, java.class.path=/Users/gaogzhen/.m2/repository/org/junit/platform/junit-platform-launcher/1.9.0/junit-platform-launcher-1.9.0.jar:// 省略。。。}]}
resolver: org.springframework.beans.factory.config.EmbeddedValueResolver@36546a22
resourceLoader: org.springframework.context.annotation.AnnotationConfigApplicationContext@5ba88be8, started on Tue Mar 21 11:44:23 CST 2023
applicationEventPublisher: org.springframework.context.annotation.AnnotationConfigApplicationContext@5ba88be8, started on Tue Mar 21 11:44:23 CST 2023
messageSource: org.springframework.context.annotation.AnnotationConfigApplicationContext@5ba88be8, started on Tue Mar 21 11:44:23 CST 2023
applicationStartup: org.springframework.core.metrics.DefaultApplicationStartup@60f7cc1d
applicationContext: org.springframework.context.annotation.AnnotationConfigApplicationContext@5ba88be8, started on Tue Mar 21 11:44:23 CST 2023
postConstruct
Bean初始化操作会执行2个步骤:
我们回到AbstractAutowireCapableBeanFactory的initializeBean()方法,继续跟踪
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 执行aware接口方法
// 初始化前操作
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
// 省略。。。
return wrappedBean;
}
继续执行invokeInitMethods()方法,代码如下:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
((InitializingBean) bean).afterPropertiesSet();
}
if (mbd != null && bean.getClass() != NullBean.class) {
String[] initMethodNames = mbd.getInitMethodNames();
if (initMethodNames != null) {
for (String initMethodName : initMethodNames) {
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd, initMethodName);
}
}
}
}
}
第一部分,InitializingBean接口相关
第二部分,检查是否有自定义的初始化方法并执行自定义的初始化方法。
实例测试代码如下所示:
package com.gaogzhen.myspring.service;
import org.springframework.beans.factory.InitializingBean;
/**
* @author gaogzhen
*/
public class InitializingService implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("InitializingBean afterPropertiesSet");
}
public void initMethod() {
System.out.println("自定义初始化方法");
}
}
@Test
public void testInitializing() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(InitializingService.class)
.setInitMethodName("initMethod")
.getBeanDefinition();
factory.registerBeanDefinition("initService", beanDefinition);
System.out.println(factory.getBean("initService"));
}
测试结果:
InitializingBean afterPropertiesSet
自定义初始化方法
com.gaogzhen.myspring.service.InitializingService@5674e1f2
完成上面初始化操作后,我们在回到initializeBean()方法,看看接下来会执行什么?
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 省略。。。
// 初始化操作
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
进入applyBeanPostProcessorsAfterInitialization方法查看
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
测试示例代码如下:
@Test
public void testAfterInitializaiton() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + "==postProcessAfterInitialization==" + bean);
return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
}
});
BeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(String.class)
.addConstructorArgValue("公众号【我眼中的互联网世界】")
.getBeanDefinition();
factory.registerBeanDefinition("afterInit", beanDefinition);
System.out.println(factory.getBean("afterInit"));
}
测试结果:
afterInit==postProcessAfterInitialization==公众号【我眼中的互联网世界】
公众号【我眼中的互联网世界】
所有单例bean实例化完成之后,spring会回调下面这个接口:
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}
调用逻辑在下面这个方法中
/* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton的bean,调用他们的afterSingletonsInstantiated方法。
我们通过ApplicaitonContext常用的refresh方法来追踪下,首先来到AbstractApplication中的fresh方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 省略。。。
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//省略。。。
}
finishBeanFactoryInitialization初始化所有剩余的非懒惰初始化的beans,代码如下
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 省略。。。
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
执行BeanFactory的preInstantiateSingletons方法,实际调用DefaultListableBeanFactory的preInstantiateSingletons方法,代码如下:
@Override
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
smartSingleton.afterSingletonsInstantiated();
smartInitialize.end();
}
}
}
示例测试,通过ApplicationContext自动回调SmartInitializingSingleton:
package com.gaogzhen.myspring.service;
import org.springframework.stereotype.Service;
/**
* 测试SmartInitializingSingleton
* @author gaogzhen
*/
@Service
public class Service1 {
public Service1() {
System.out.println("service1 初始化完成");
}
}
package com.gaogzhen.myspring.service;
import org.springframework.stereotype.Service;
/**
* 测试SmartInitializingSingleton
* @author gaogzhen
*/
@Service
public class Service2 {
public Service2() {
System.out.println("service2 初始化完成");
}
}
package com.gaogzhen.myspring.processors;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.stereotype.Component;
/**
* @author gaogzhen
*/
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {
@Override
public void afterSingletonsInstantiated() {
System.out.println("所有bean初始化完毕");
}
}
package com.gaogzhen.myspring.test;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {"com.gaogzhen.myspring"})
public class TestSmartInitializingSingleton {
@Test
public void testAfterSingletonsInstantiated() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(TestSmartInitializingSingleton.class);
System.out.println("开始启动容器");
context.refresh();
System.out.println("容器启动完毕");
}
}
测试结果:
开始启动容器
// 省略日志信息。。。
2023-03-22 10:19:02 407 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service1'
service1 初始化完成
2023-03-22 10:19:02 407 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
service2 初始化完成
所有bean初始化完毕
容器启动完毕
如果小伙伴什么问题或者指教,欢迎交流。
❓QQ:806797785
⭐️源代码仓库地址:https://gitee.com/gaogzhen/spring6-study
参考:
[1]Spring系列之Bean生命周期详解[CP/OL]