【学习】json格式的AbstractApplicationContext.refresh()

本文深入剖析Spring容器的启动过程,重点介绍了invokeBeanFactoryPostProcessors和finishBeanFactoryInitialization两个核心方法。涵盖BeanFactoryPostProcessor和BeanPostProcessor的执行顺序,以及Spring如何处理非懒加载的单例bean实例化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

用json格式记录的refreash方法,有需要的小伙伴可以看看,核心方法其实就是invokeBeanFactoryPostProcessors和finishBeanFactoryInitialization
参考:

{
“remark”: “spring容器启动流程”,
“AbstractApplicationContext.refresh()”: [
{
“remark”: "初始化配置,并检测,通过springboot启动的应用,没有特殊内容,暂时不管 ",
“originalRemark”: "Prepare this context for refreshing. ",
“AbstractApplicationContext.prepareRefresh”: [
“AbstractApplicationContext.initPropertySources”,
“AbstractApplicationContext.getEnvironment().validateRequiredProperties()”
]
},
{
“remark”: “初始化bean工厂”,
“originalRemark”: "Tell the subclass to refresh the internal bean factory. ",
“AbstractApplicationContext.obtainFreshBeanFactory”: [
“1. 设置容器id”,
“2. 返回bean工厂”
]
},
{
“remark”: “容器准备”,
“originalRemark”: “Prepare the bean factory for use in this context”,
“AbstractApplicationContext.prepareBeanFactory”: [
“1. bean属性设置 setBeanClassLoader setBeanExpressionResolver addPropertyEditorRegistrar”,
“2. 增加BeanPostProcessor ApplicationContextAwareProcessor ApplicationListenerDetector”,
“3. ignoreDependencyInterface 依赖注入时忽略这些依赖,在AbstractAutowireCapableBeanFactory.populateBean方法中调用,会过滤这些依赖”,
“4. registerResolvableDependency 依赖注入某些接口,返回对应的对象,详细见resolvableDependencies 用法”,
“5. 将环境变量注入容器中,”
]
},
{
“remark”: “容器后置处理,目前实现为空”,
“originalRemark”: “Allows post-processing of the bean factory in context subclasses.”,
“AbstractApplicationContext.postProcessBeanFactory”: {
}
},
{
“remark”: “触发容器后置处理器执行”,
“originalRemark”: “Invoke factory processors registered as beans in the context”,
"AbstractApplicationContext.invokeBeanFactoryPostProcessors 内部调用 ": [
{
"如果容器是:BeanDefinitionRegistry(bean定义注册器?)特殊处理BeanDefinitionRegistryPostProcessor,调用它的postProcessBeanDefinitionRegistry方法, ": [
“在mybatis中就是实现了该接口”,
“1. 【处理容器中已有的processor】,”,
“2. 【处理容器中定义的实现了PriorityOrdered】”,
“3. 【处理容器中定义的实现了Ordered】”,
“4. 【处理容器中定义的没有实现上诉接口的】”,
“重要的BeanDefinitionRegistryPostProcessor=============:”,
“ConfigurationClassPostProcessor: 用来处理ComponentScans 和 ComponentScan,PropertySource,PropertySources等配置的,他的扫描就是ClassPathBeanDefinitionScanner,mybatis和这个一模一样”,
“MapperScannerConfigurer mybatis配置类 他的整体逻辑很像上面的ConfigurationClassPostProcessor”,
“PropertySourcesPlaceholderConfigurer 加载各种配置,也会加载EnvironmentAware 部分配置 https://www.jianshu.com/p/a3c7ff0de5ac”,
"PropertyPlaceholderConfigurer 与上面只相差一个EnvironmentAware 接口实现 ",
“但是@value属性是在AnnotationXXXX中处理的,在AbstractBeanFactory.resolveEmbeddedValue中调用的”,
"EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor ",
“EventListenerMethodProcessor 在这一步初始化eventListenerFactories”,
“SmartInitializingSingleton 的执行时机是bean初始化完成之后”,
“”,
"ConfigurationBeanFactoryMetadata "
],
“否者 invokeBeanFactoryPostProcessors”: “”
},
“再从容器中获取BeanFactoryPostProcessor,分别按PriorityOrdered,ordered,没有顺序的依次执行postProcessBeanFactory”,
“重要的BeanFactoryPostProcessor===============”
]
},
{
“remark”: “注册BeanPostProcessor”,
“AbstractApplicationContext.registerBeanPostProcessors”: [
{
“prepareBeanFactory期间创造的”: [
“ApplicationContextAwareProcessor 这个类在bean初始化时,处理EnvironmentAware,ResourceLoaderAware等”,
“WebApplicationContextServletContextAwareProcessor 处理 ServletContextAware ServletConfigAware等”,
"ImportAwareBeanPostProcessor 处理ImportAware "
]
},
{
“PriorityOrdered”: [
“ConfigurationPropertiesBindingPostProcessor 触发时机是在 initializeBean 暂忽略”,
“CommonAnnotationBeanPostProcessor 处理初始化方法,invokeInitMethods,处理@PostConstruct等方法”,
“AutowiredAnnotationBeanPostProcessor 在populate 那已经处理了,用于处理@Autowire和@Value”
]
},
{
“summary”: "这三个都是 AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator ",
“Ordered”: [
{
"AnnotationAwareAspectJAutoProxyCreator ": [
"AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator ",
“AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware”,
“SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor extends BeanPostProcessor”,
{
“wrapIfNecessary”: [
“isInfrastructureClass 判断是不是Advisor 等相关的类 shouldSkip 判断是否需要跳过,”,
“找到配置的拦截器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)”,
{
“创建代理AbstractAutoProxyCreator.createProxy”: [
“为beanDefinition 设置ORIGINAL_TARGET_CLASS_ATTRIBUTE属性”,
“构建ProxyFactory”,
{
“ProxyFactory.getProxy(java.lang.ClassLoader)”: [
“返回代理工厂类 org.springframework.aop.framework.ProxyCreatorSupport.getAopProxyFactory”,
"根据配置或者类属性,返回对应的代理 org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy ",
{
“CglibAopProxy.getProxy(java.lang.ClassLoader)”: [
"组装 Cglib Enhancer ",
“创建代理”,
“执行调用CglibMethodInvocation.invokeJoinpoint”
]
}
]
}
]
}
]
}
]
},
“AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor extends AbstractAdvisingBeanPostProcessor implements BeanFactoryAware”,
"AbstractAdvisingBeanPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor ",
“ProxyProcessorSupport extends ProxyConfig implements Ordered, BeanClassLoaderAware, AopInfrastructureBean”,
“实现和aop注解的差不多,就是特殊处理,已经是代理对象的情况,如果没有再组装ProxyFactory,后面就和上面一样了”,
",
“MethodValidationPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor implements InitializingBean”,
“这个就和AsyncAnnotationBeanPostProcessor完全一样了,这两个就是注解不一样”
]
},
{
“NoneOrdered”: [
"ErrorPageRegistrarBeanPostProcessor ",
"WebServerFactoryCustomizerBeanPostProcessor "
]
},
{
"MergedBeanDefinitionPostProcessor ": [
“CommonAnnotationBeanPostProcessor 处理初始化方法,invokeInitMethods,处理@PostConstruct等方法”,
"AutowiredAnnotationBeanPostProcessor 在populate 那已经处理了,用于处理@Autowire和@Value "
]
}
]
},
{
“remark”: “初始化国际化资源,用于异常提示之类的,暂放弃”,
“originalRemark”: “Initialize message source for this context.”,
“AbstractApplicationContext.initMessageSource”: {
}
},
{
“remark”: “初始化事件广播器,便于后面广播,大概是观察者模式吧,暂不看”,
“originalRemark”: “Initialize event multicaster for this context.”,
“AbstractApplicationContext.initApplicationEventMulticaster”: {
}
},
{
“remark”: “空白”,
“originalRemark”: “空白”,
“AbstractApplicationContext.onRefresh”: {
}
},
{
“remark”: “为了上面的事件通知器,添加listener,发生事件时,通知这些类”,
“originalRemark”: “Check for listener beans and register them.”,
“AbstractApplicationContext.registerListeners”: {
}
},
{
“remark”: “初始化所有的非懒加载的类”,
“originalRemark”: “Instantiate all remaining (non-lazy-init) singletons.”,
“AbstractApplicationContext.finishBeanFactoryInitialization”: [
{
“remark”: “实例化所有的非懒加载的 单例”,
“DefaultListableBeanFactory.preInstantiateSingletons”: [
{
“1. foreach 所有的bean定义 进行实例化”: [
“1. 工厂bean特殊判断”,
{
“2. 调用getBean -> 调用doGetBean(这里忽略从缓存中拿的逻辑)”: [
“1. 从父类中拿”,
“2. final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);”,
“3. 处理dependsOn, 从容器中获取依赖的bean”,
{
“4. getSingleton -> createBean”: [
“(Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.)”,
“resolveBeforeInstantiation 在bean初始化之前,尝试提前返回一个代理类”,
“实际是:InstantiationAwareBeanPostProcessor特殊处理,如果返回不是空,则返回该代理”,
"简单配置后发现没有返回bean的, XXX暂时不管XXX ",
"
=============”,
{
“doCreateBean”: [
{
“applyMergedBeanDefinitionPostProcessors”: [
“调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition”
]
},
{
“populateBean”: [
“特殊处理:InstantiationAwareBeanPostProcessor, AutowiredAnnotationBeanPostProcessor 就是在这处理的,调用postProcessProperties”
]
},
{
“initializeBean”: [
“invokeAwareMethods 内部有3个aware接口,beanName,BeanFactory,classLoader”,
“applyBeanPostProcessorsBeforeInitialization 处理BeanPostProcessor postProcessBeforeInitialization,例如applicationContext, postConstruct”,
“invokeInitMethods:(InitializingBean ,指定initMethod)”,
“applyBeanPostProcessorsAfterInitialization 处理BeanPostProcessor postProcessAfterInitialization,例如三个代理实现等”
]
},
{
“registerDisposableBeanIfNecessary”: []
}
]
}
]
}
]
}
]
},
“2. SmartInitializingSingleton 后置处理,Trigger post-initialization callback for all applicable beans…”
]
}
]
},
{
“remark”: “事件通知等”,
“AbstractApplicationContext.finishRefresh”: {
}
}
]
}

java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@2e179f3e testClass = com.swt.spring_ssmp.BookDaoTest, locations = [], classes = [com.swt.spring_ssmp.SpringSsmpApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@1b2abca6, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@342c38f8, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@729d991e, org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@7d4f9aae, org.springframework.boot.test.context.SpringBootTestAnnotation@79beab09], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180) at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:191) at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:130) at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260) at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163) at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735) at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734) at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762) at java.base/java.util.Optional.orElseGet(Optional.java:364) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) Caused by: java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getTypeForFactoryBeanFromAttributes(FactoryBeanRegistrySupport.java:86) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryBean(AbstractAutowireCapableBeanFactory.java:837) at org.springframework.beans.factory.support.AbstractBeanFactory.isTypeMatch(AbstractBeanFactory.java:652) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:575) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:534) at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:138) at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) at org.springframework.boot.SpringApplication.run(SpringApplication.java:334) at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454) at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137) at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225) at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152) ... 17 more
最新发布
06-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值