docs/Spring全家桶/Spring源码分析/Spring启动流程/Spring启动流程(五):执行BeanFactoryPostProcessor.md
ģǼ
postProcessBeanFactory(beanFactory)spring ṩչ㣬κιܣʵ֣AbstractApplicationContext postProcessBeanFactory £
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
ǰʹõ ApplicationContext AnnotationConfigApplicationContextûʵ
BeanFactoryPostProcessors: invokeBeanFactoryPostProcessors(beanFactory)
BeanFactoryPostProcessorΪ beanFactory ĺô beanFactory һЩΪBeanFactoryPostProcessorϸԲο spring ֮ BeanFactoryPostProcessors
BeanFactoryPostProcessorἸ㣺
BeanFactoryPostProcessor Ϊ֣BeanFactoryPostProcessor BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor ķִ BeanFactoryPostProcessor ķ˽ЩǸ룬ԲҪֻ£
|-AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(String...)
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#invokeBeanFactoryPostProcessors
|-PostProcessorRegistrationDelegate
#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)
ֱӿ invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// дڵBeanDefinitionRegistryPostProcessor
Set<String> processedBeans = new HashSet<>();
//beanFactoryDefaultListableBeanFactoryBeanDefinitionRegistryʵ࣬Կ϶if
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//regularPostProcessors BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors BeanDefinitionRegistryPostProcessor
//BeanDefinitionRegistryPostProcessor չ BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// ѭbeanFactoryPostProcessors£beanFactoryPostProcessors϶û
// ΪbeanFactoryPostProcessorsǻֶӵģspringɨ
// ֶֻannotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX)Ż
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// жpostProcessorDzBeanDefinitionRegistryPostProcessor
// ΪBeanDefinitionRegistryPostProcessor չBeanFactoryPostProcessor
// ҪжDzBeanDefinitionRegistryPostProcessor, ǵĻֱִ
// postProcessBeanDefinitionRegistryȻѶװregistryProcessorsȥ
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
//ǵĻװregularPostProcessors
regularPostProcessors.add(postProcessor);
}
}
// һʱװBeanDefinitionRegistryPostProcessor
// BeanDefinitionRegistry̳PostProcessorBeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// ʵBeanDefinitionRegistryPostProcessorӿڵBeanName
// springڲṩBeanDefinitionRegistryPostProcessor
// ԼԼʵֵBeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//ConfigurationClassPostProcessor࣬ҷŵcurrentRegistryProcessors
//ConfigurationClassPostProcessorǺҪһ࣬ʵ
//BeanDefinitionRegistryPostProcessorӿڣ
//BeanDefinitionRegistryPostProcessorӿʵBeanFactoryPostProcessorӿ
//ConfigurationClassPostProcessorǼҪ, ִ
//ɨ @Bean@Import@ImportResource ȸֲ
currentRegistryProcessors.add(beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//
sortPostProcessors(currentRegistryProcessors, beanFactory);
//ϲProcessorsΪʲôҪϲΪregistryProcessors
//װBeanDefinitionRegistryPostProcessor
//һʼʱspringִֻBeanDefinitionRegistryPostProcessorеķ
//ִBeanDefinitionRegistryPostProcessorķBeanFactoryProcessorķ
//ҪѴһУͳһִиķ
registryProcessors.addAll(currentRegistryProcessors);
//ΪִConfigurationClassPostProcessorpostProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//ΪcurrentRegistryProcessorsһʱҪ
currentRegistryProcessors.clear();
// ٴθBeanDefinitionRegistryPostProcessorBeanName
// BeanNameǷѾִйˣûʵOrderedӿ
// ûбִйҲʵOrderedӿڵĻѶ͵currentRegistryProcessors
// ͵processedBeans
// ûʵOrderedӿڵĻﲻݼӵcurrentRegistryProcessors
// processedBeansУ
// ſԻǶʵBeanDefinitionRegistryPostProcessorBean
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//
sortPostProcessors(currentRegistryProcessors, beanFactory);
//ϲProcessors
registryProcessors.addAll(currentRegistryProcessors);
//ִԶBeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//ʱ
currentRegistryProcessors.clear();
// ĴִʵOrderedӿڵBeanDefinitionRegistryPostProcessor
// ĴִûʵOrderedӿڵBeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(
BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(
ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// registryProcessorsװBeanDefinitionRegistryPostProcessor
// ĴִеķҪٰѸķҲִһ
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//regularPostProcessorsװBeanFactoryPostProcessorִBeanFactoryPostProcessorķ
//regularPostProcessorsһ£Dzݵģ
//ֶֻBeanFactoryPostProcessorŻ
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//ѭBeanName
for (String ppName : postProcessorNames) {
//Beanִйˣ
if (processedBeans.contains(ppName)) {
}
//ʵPriorityOrderedӿڣ뵽priorityOrderedPostProcessors
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory
.getBean(ppName, BeanFactoryPostProcessor.class));
}
//ʵOrderedӿڣ뵽orderedPostProcessorNames
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//ûʵPriorityOrderedҲûʵOrdered뵽nonOrderedPostProcessorNames
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// priorityOrderedPostProcessorsʵPriorityOrderedӿڵBeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ִpriorityOrderedPostProcessors
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// ִʵOrderedӿڵBeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors
= new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(
postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// ִмûʵPriorityOrderedӿڣҲûʵOrderedӿڵBeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors
= new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(
postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
}
dzdzѣִѭ⼸
BeanDefinitionRegistryPostProcessorִ BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor ˳£
BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor``ConfigurationClassPostProcessorᴦĿе @ComponentScan``@Component``@Import``@Bean ע⣬ûԶ BeanDefinitionRegistryPostProcessor``BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorҲһмص BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor ˳£
PriorityOrdered ӿڵ BeanFactoryPostProcessorOrdered ӿڵ BeanFactoryPostProcessorBeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor ࣬ͬҪִ BeanFactoryPostProcessor ķ˵ִ BeanDefinitionRegistryPostProcessorִָ PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessorsִ BeanFactoryPostProcessor ִָ BeanFactoryPostProcessor#postProcessBeanFactory
ݺǶϷϸˣ
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry:
applicationContext.addBeanFactoryPostProcessor ӵ BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistry һ£ֶ߲ø÷;PriorityOrdered ӿڵ BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistryOrdered ӿδִй BeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistryBeanDefinitionRegistryPostProcessor postProcessBeanDefinitionRegistryBeanFactoryPostProcessor#postProcessBeanFactory
applicationContext.addBeanFactoryPostProcessor ӵ BeanDefinitionRegistryPostProcessor postProcessBeanFactory һ£ֶ߲ø÷;PriorityOrdered BeanFactoryPostProcessor postProcessBeanFactoryOrdered BeanFactoryPostProcessor postProcessBeanFactoryBeanFactoryPostProcessor postProcessBeanFactoryԿʵʾΪִBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactoryҪעǣBeanDefinitionRegistryPostProcessor BeanFactoryPostProcessor ࣬ڵ BeanFactoryPostProcessor#postProcessBeanFactory ʱ ʵҲ BeanDefinitionRegistryPostProcessor postProcessBeanFactory .
ϵ BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactory ִУִЩأͨ demo01ִеĴ£
1.2 ʱִ ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry1.4 ʱִ ConfigurationClassPostProcessor#postProcessBeanFactory2.4 ʱִ EventListenerMethodProcessor#postProcessBeanFactoryţDZչʲô
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry ִһȥԲҪķֻʾջ
AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.String...)
|-AbstractApplicationContext#refresh
|-AbstractApplicationContext#invokeBeanFactoryPostProcessors
|-PostProcessorRegistrationDelegate
#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)
|-PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
|-ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
|-ConfigurationClassPostProcessor#processConfigBeanDefinitions
ֱӽ ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
//ѭcandidateNames
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// ڲλǷѾ
// һ֪ʶä
// עʱԲConfigurationע⣬
// ֱʹComponent ComponentScan Import ImportResourceע⣬֮ΪLite
// Configurationע⣬ͳ֮ΪFull
// עLite࣬getBean࣬ᷢԭǸ
// עFull࣬getBean࣬ᷢѾԭǸˣ
// Ѿcgilb
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug(...);
}
}
// жǷΪ࣬
// 1\. @Configuration ע proxyBeanMethods != false ࣬spring Ϊ Full
// 2\. @Configuration ע proxyBeanMethods == false,
// @Component@ComponentScan@Import@ImportResource
// @Bean ֮һע࣬spring Ϊ Lite
// FullLitebeanDefбʶ
else if (ConfigurationClassUtils
.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// ûֱ࣬ӷ
if (configCandidates.isEmpty()) {
return;
}
//
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
SingletonBeanRegistry sbr = null;
// DefaultListableBeanFactoryջʵSingletonBeanRegistryӿڣԿԽ뵽if
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
//springпĬϵbeanʽǿûûԶbeanʽ
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//࣬˺ܶ£
//磺@Component@PropertySources@ComponentScans@ImportResourceȵĴ
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses
= new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// ֱһŰImport࣬@Bean @ImportRosource תBeanDefinition
this.reader.loadBeanDefinitions(configClasses);
// configClasses뵽alreadyParsed
alreadyParsed.addAll(configClasses);
candidates.clear();
// עBeanDefinition candidateNamesбȽ
// ڵĻ˵µBeanDefinitionע
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
// ѭalreadyParsed뵽alreadyParsedClasses
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils
.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
ϷǶ BeanDefinition ϢĽһƣ @Configuration``@PropertySources``@ComponentScans``@ImportResource ȵĴ demo01 ûЩע⣬ǾͲչˣٷ
ConfigurationClassPostProcessor#postProcessBeanFactoryConfigurationClassPostProcessor postProcessBeanFactory Ƚϼ»Ƕ @Configuration ǿ
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// ʡ
// ConfigurationClasses ǿ
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
// ʡ
// ȫࣺ
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// Set enhanced subclass of the user-specified bean class
// ǿ
Class<?> configClass = beanDef.getBeanClass();
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
if (configClass != enhancedClass) {
beanDef.setBeanClass(enhancedClass);
}
}
}
demo01 û @ConfigurationͲչˣٷ
EventListenerMethodProcessor#postProcessBeanFactory¼ģֱϴ룺
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.beanFactory = beanFactory;
Map<String, EventListenerFactory> beans
= beanFactory.getBeansOfType(EventListenerFactory.class, false, false);
List<EventListenerFactory> factories = new ArrayList<>(beans.values());
AnnotationAwareOrderComparator.sort(factories);
this.eventListenerFactories = factories;
}
Կ spring Уóе EventListenerFactoryȻֵ this.eventListenerFactoriesͲչˡ
Ľ invokeBeanFactoryPostProcessors ִ̣ΪִBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry BeanFactoryPostProcessor#postProcessBeanFactoryִй£
ͨԷ֣invokeBeanFactoryPostProcessors һִ BeanFactoryPostProcessor
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistryConfigurationClassPostProcessor#postProcessBeanFactoryEventListenerMethodProcessor#postProcessBeanFactoryУConfigurationClassPostProcessor һdzdzҪ BeanFactoryPostProcessorĽһԲο£
ԭӣhttps://my.oschina.net/funcy/blog/4641114 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע