🌈 个人主页:danci_
🔥 系列专栏:《设计模式》《MYSQL》
💪🏻 制定明确可量化的目标,坚持默默的做事。
✨欢迎加入探索MYSQL索引数据结构之旅✨
👋 Spring框架的浩瀚海洋中,InitializingBean如同一颗闪闪发光的珍珠,等待被你发现。这一隐藏的宝藏,能够让你的Spring应用在初始化时更灵活、可控。本篇文章将带你深入探索InitializingBean的奥秘,揭示其在Spring生命周期中的重要作用,让你的开发之路更加顺畅高效。准备好开启这段奇妙的探索之旅了吗?让我们一起揭开InitializingBean的神秘面纱吧!
目录
一、环境
二、示例
2.1、说明
三、执行过程
3.1 源码解析
一、环境
- jdk: 1.8
- spring-boot: 2.7.1
二、示例
@Component
public class TestInit implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("调用TestInit.afterPropertiesSet方法");
}
}
运行结果:
2.1、说明
- springboot提供InitializingBean接口,用户可以实现之来自定义初始化操作
- 实现InitializingBean接口重写afterPropertiesSet方法并注册到spring容器中,创建实例后即可触发执行自定义初始化操作
三、执行过程
一直很好奇和想弄清楚什么时候调扩展点afterPropertiesSet()方法呢?用什么方式调用?
为满足好奇,启动一个简单springboot项目跟踪源码执行过程如下:
3.1 源码解析
1. Springboot项目启动入口SpringApplication.run
public ConfigurableApplicationContext run(String... args) {
// 记录启动开始时间
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 准备ApplicationContext
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
// 从spring.factories 中获取监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
// 发布事件
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 环境参数
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 配置设置进系统参数
configureIgnoreBeanInfo(environment);
// 输出banner
Banner printedBanner = printBanner(environment);
// 创建applicationContext IOC容器
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 准备上下文IOC容器,设置了一系列的属性值
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 308行,启动spring容器
refreshContext(context);
// 刷新后的处理
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
// 发布事件
listeners.started(context, timeTakenToStartup);
// 调用 runner,实现了 ApplicationRunner或CommandLineRunner 的接口
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
这里关注调refreshContext(context)来启动容器
2. SpringApplication.refreshContext启动容器
protected void refresh(ConfigurableApplicationContext applicationContext) {
// 734行
applicationContext.refresh();
}
然后调AbstractApplicationContext.refresh()来启动Spring容器
3. AbstractApplicationContext.refresh()启动Spring容器
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 启动容器前准备。启动时间、状态和环境等
prepareRefresh();
// 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备在上下文中使用bean工厂
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 调用在上下文中注册为bean的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册拦截bean创建的bean处理器。
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 为此上下文初始化消息源。
initMessageSource();
// 初始化事件广播器
initApplicationEventMulticaster();
// 初始化特定上下文子类中的其他特殊bean。
onRefresh();
// 注册事件监听器
registerListeners();
// 583行,实例化所有剩余的(非lazy-init)单例
finishBeanFactoryInitialization(beanFactory);
// 完成启动操作
finishRefresh();
}
catch (BeansException ex) {
...
}
finally {
resetCommonCaches();
contextRefresh.end();
}
}
}
列出了Spring容器启动的整个过程。本例关注InitializingBean扩展点,其它内容不详细解读。 实例化所有剩余的(非lazy-init)单例 finishBeanFactoryInitialization(beanFactory);
4. AbstractApplicationContext.finishBeanFactoryInitialization(...)初始化(非lazy-init)单例
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
...
// 918行,实例化所有剩余的(非lazy-init)单例。
beanFactory.preInstantiateSingletons();
}
调bean工厂类的preInstantiateSingletons方法来实例化bean
5. ConfigurableListableBeanFactory.preInstantiateSingletons()实例化bean
@Override
public void preInstantiateSingletons() throws BeansException {
...
// 955行,获取bean
getBean(beanName);
...
}
这里由调父父类AbstractBeanFactory.getBean来获取bean
6.AbstractBeanFactory.getBean(beanName)获取bean
public Object getBean(String name) throws BeansException {
// 208行
return doGetBean(name, null, null, false);
}
然后调本类doGetBean(...)方法获取bean
7. AbstractBeanFactory.doGetBean获取bean
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
...
// 332行,创建bean实例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
...
}
});
...
}
...
}
return adaptBeanInstance(name, beanInstance, requiredType);
}
然后调子类的createBean来创建实例
8.AbstractAutowireCapableBeanFactory.createBean(...)创建实例
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
// 542行
doCreateBean(beanName, mbdToUse, args);
...
}
调本类doCreateBean
9.AbstractAutowireCapableBeanFactory.doCreateBean(...)执行创建bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
...
// 实例化 Bean
// 解决循环依赖问题, 是否允许循环依赖 等
...
// 属性装配, 即自动注入
populateBean(beanName, mbd, instanceWrapper);
// 620行,应用工厂回调以及初始化方法和bean后处理程序。
// 例如init-method、InitializingBean 接口、BeanPostProcessor 接口
exposedObject = initializeBean(beanName, exposedObject, mbd);
...
}
10. AbstractAutowireCapableBeanFactory.initializeBean处理初始化完成处理
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
...
// 方法回调
invokeInitMethods(beanName, wrappedBean, mbd);
...
}
11. AbstractAutowireCapableBeanFactory.invokeInitMethods实例的方法回调处理
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
// 判断为InitializingBean的实现类,且重写afterPropertiesSet方法,则调afterPropertiesSet方法
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
...
((InitializingBean) bean).afterPropertiesSet();
...
}
...
}
到此,探索InitializingBean已完。
ps: 以上是研读源码加上翻阅许多文献理解的总结,如有错误或不足的地方,欢迎指出,欢迎留言交流。我会继续努力学习和分享更多有干货的内容。