目录
- AnnotationConfigApplicationContext 测试代码
- 手动注册第1个bean: LocalConfig
- 手动注册第2个bean: LocalConfig2
- refresh的postProcessBeanFactory方法
- refresh的 invokeBeanFactoryPostProcessors(beanFactory);
- BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,首先执行的是BeanDefinitionRegistryPostProcessor
- 内部的BeanDefinitionRegistryPostProcessor执行,具体是ConfigurationClassPostProcessor
- BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,接下来执行的是实现了Ordered的
- BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,继续执行其它常规的BeanFactoryPostProcessor
- 执行完BeanDefinitionRegistry类型的BeanFactoryPostProcessor后,类似的处理其它类型的BeanFactoryPostProcessor
- 完成BeanDefinition注册,回到refresh方法继续
- 总结
AnnotationConfigApplicationContext 测试代码
@Test
public void testAdd() throws Exception {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(LocalConfig.class, LocalConfig2.class);
UserService service = (UserService)ctx.getBean("userService");
Assert.assertNotNull(service);
service.add(new User());
service.destroy();
}
如下直接开始debug流程
目录可以设置如下
手动注册第1个bean: LocalConfig
@EnableAspectJAutoProxy
@Configuration
@ComponentScan("com.aop.test")
public class LocalConfig {
public LocalConfig(){
System.out.println("LocalConfig()");
}
}
手动注册第2个bean: LocalConfig2
@EnableAspectJAutoProxy
@Configuration
public class LocalConfig2 {
public LocalConfig2(){
System.out.println("LocalConfig2()");
}
@Bean
public X x() {
System.out.println("start new X");
return new X();
}
}
refresh方法执行前
- 两个手动注册的bean是AnnotatedGenericBeanDefinition类型
- beanFactoryPostProcessors 数量为0
技巧
备注:可以在关心的地方执行表达式查看自己关心的东西是否变化了; 如下关心beanDefinitionMap是否变化
可以添加watch (debug技巧更多则要google下了)
refresh的postProcessBeanFactory方法
在本例中不对如下两个产生变化,先跳过
((AnnotationConfigApplicationContext) this).beanFactoryPostProcessors
((AnnotationConfigApplicationContext) this).beanFactory.beanDefinitionMap
可以看下这个方法的描述:
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
可以自己加入BeanPostProcessors进行扩展
refresh的 invokeBeanFactoryPostProcessors(beanFactory);
这个步骤执行完成后发生了变化,需要深入细节了
BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,首先执行的是BeanDefinitionRegistryPostProcessor
本例中没有自定义BeanFactoryPostProcessor, 所有跳过。
补充:BeanDefinitionRegistry是什么?
BeanDefinitionRegistry是个接口,负责注册和管理Bean的定义信息。
/**
* Interface for registries that hold bean definitions, for example RootBeanDefinition
* and ChildBeanDefinition instances. Typically implemented by BeanFactories that
* internally work with the AbstractBeanDefinition hierarchy.
*
* <p>This is the only interface in Spring's bean factory packages that encapsulates
* <i>registration</i> of bean definitions. The standard BeanFactory interfaces
* only cover access to a <i>fully configured factory instance</i>.
*
* <p>Spring's bean definition readers expect to work on an implementation of this
* interface. Known implementors within the Spring core are DefaultListableBeanFactory
* and GenericApplicationContext.
*
* @author Juergen Hoeller
* @since 26.11.2003
* @see org.springframework.beans.factory.config.BeanDefinition
* @see AbstractBeanDefinition
* @see RootBeanDefinition
* @see ChildBeanDefinition
* @see DefaultListableBeanFactory
* @see org.springframework.context.support.GenericApplicationContext
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see PropertiesBeanDefinitionReader
*/
public interface BeanDefinitionRegistry extends AliasRegistry {
内部的BeanDefinitionRegistryPostProcessor执行,具体是ConfigurationClassPostProcessor
附:ConfigurationClassPostProcessor类图
(*)ConfigurationClassPostProcessor执行processConfigBeanDefinitions方法
此句执行完可以看到beanDefinitionMap发生了变化,所以重点查看
对两个@Configurationonfig bean进行解析
ConfigurationClassParser#parse(BeanDefinitionHolder)解析过程
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
processDeferredImportSelectors();
}
ConfigurationClassParser#doProcessConfigurationClass
直接一看可以看到componentScan了
LocalConfig配置的@ComponentScan扫描出beanDefinition并添加到beanDefinitionMap中
可以看到如下
如@import @Resource @Bean等也可以看到在此解析出来
执行到LocalConfig2全配置类可以看到解析出@Bean方法
全注解类加上扫描出来的可能的bean,再次loadBeanDefinitions得到最后所有bean
执行完成后如下:
do whitle(!candidates.isEmpty())处理完
观察代码可以看到是嵌套处理的,因为扫描出来的可能继续成为全注解类,不断的处理,直到完成,有点递归的感觉
do {
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<String>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition beanDef = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(beanDef.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(beanDef, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
ImportRegistry
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions 如下
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (singletonRegistry != null) {
if (!singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
}
了解功能,暂时跳过:
ImportAware 接口,提供被导入类的访问功能。当一个类实现了 ImportAware 接口,并且被通过 @Import 注解导入到其他配置类中,该类可以获得对导入它的 AnnotationMetadata 的访问权。
BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,接下来执行的是实现了Ordered的
经历上面漫长的执行链路后,回到主线,继续执行那些实现了Ordered的BeanFactoryPostProcessor
可以看到代码都是同上的,本例中没有实现,直接跳过
BeanDefinitionRegistry执行所有的BeanFactoryPostProcessor,继续执行其它常规的BeanFactoryPostProcessor
本例没有,跳过
执行完BeanDefinitionRegistry类型的BeanFactoryPostProcessor后,类似的处理其它类型的BeanFactoryPostProcessor
具体如下:
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(beanFactory, orderedPostProcessors);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
所以可以看到BeanFactoryPostProcessor内部执行有区分,有先后次序
完成BeanDefinition注册,回到refresh方法继续
所以执行完invokeBeanFactoryPostProcessors(beanFactory);
后所有的BeanDefinition已经注册好了
总结
new AnnotationConfigApplicationContext(LocalConfig.class, LocalConfig2.class);
register(annotatedClasses);
refresh()
invokeBeanFactoryPostProcessors(beanFactory);
先BeanDefinitionRegistry类型的;按照内部的、order顺序、其它依此执行
其中重要的BeanDefinitionRegistry类型的BeanFactoryPostProcessor为ConfigurationClassPostProcessor
再PriorityOrdered的BeanFactoryPostProcessors
再Ordered的
最后其它的
至此完成invokeBeanFactoryPostProcessors方法的执行,完成beanDefinition的注册
而ConfigurationClassPostProcessor执行过程中,会对诸如@ComponentScan @Import, @Bean等解析; 所以了解细节可以再次认真读一下ConfigurationClassPostProcessor代码,其过程是复杂的。 整个流程有很多可以借鉴的代码写法
标签:AnnotationConfigApplicationContext,beanFactory,BeanFactoryPostProcessor,Componen From: https://blog.csdn.net/qq_26437925/article/details/144865082