在執行refreshContext刷新上下文的過程中,首次執行了對BeanFactoryPostProcessor后置處理器的執行,此時BeanFactory容器中有兩個bean工廠后置處理器:
ConfigurationWarningsApplicationContextInitializer.ConfigurationWarningsPostProcessor
SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor,
接下來我們看執行BeanFactoryPostProcessor的入口:invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors
方法內部首先調用了PostProcessorRegistrationDelegate后置處理器注冊委派者的invokeBeanFactoryPostProcessors方法
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
//實例化並調用所有已注冊的BeanFactoryPostProcessor bean,如果給出顯式順序,則遵循此順序。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
}
PostProcessorRegistrationDelegate
后置處理器注冊委派者主要是根據首要類及其上面的配置,對config class進行解析,同時根據Configuration class加載BeanDefinition;同時注冊了屬性占位符后置處理器、Aop代理后置處理器
final class PostProcessorRegistrationDelegate {
/**
*警告:雖然看起來這個方法的主體可以很容易地重構以避免使用多個循環和多個列表,
*但使用多個列表和多次傳遞處理器名稱是有意為之的。我們必須確保我們尊重優先訂購和訂購處理器的合同。
*特別地,我們不能讓處理器以錯誤的順序被實例化(通過getBean()調用)或在ApplicationContext中注冊。
*
*
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//定義一個處理過的bean集合
Set<String> processedBeans = new HashSet<>();
//如果beanFactory 是一個BeanDefinition注冊器
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//定義一個常規的后置處理器集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//定義一個 Bean定義注冊表后處理集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判斷postProcessor 是否是BeanDefinitionRegistryPostProcessor類型,然后強轉成BeanDefinitionRegistryPostProcessor ,
//調用registryProcessor的postProcessBeanDefinitionRegistry方法,首先調用的是CachingMetadataReaderFactoryPostProcessor的方法,接下來調用ConfigurationWarningsPostProcessor的方法
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//執行完postProcessBeanDefinitionRegistry方法,將執行完的后置處理器添加到registryProcessors集合中
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//不要在這里初始化FactoryBeans:我們需要讓所有常規bean保持未初始化狀態,
//以便bean工廠后處理程序應用於它們!
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
//首先,調用實現優先排序的BeanDefinitionRegistryPostProcessors,postProcessorNames = org.springframework.context.annotation.internalConfigurationAnnotationProcessor,class = ConfigurationClassPostProcessor
//根據類型獲取BeanDefinitionMap中的postProcessorNames internalConfigurationAnnotationProcessor
//,此時符合條件的只有internalConfigurationAnnotationProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//將當前bean加入到集合中,得到ConfigurationClassPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//此方法調用獲取到的BeanDefinitionRegistryPostProcessors 類型的對象進行處理
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
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);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
//最后,調用所有其他BeanDefinitionRegistryPostProcessors,直到不再出現其他的
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, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
//priorityOrderedPostProcessors = [propertySourcesPlaceholderConfigurer],此處通過調用屬性源占位符配置器的postProcessBeanFactory方法,添加了屬性源調用者,通過key獲取value
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// [DependsOnDatabaseInitializationPostProcessor]
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
//
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//0 = {EventListenerMethodProcessor@6521}
//1 = {ErrorMvcAutoConfiguration$PreserveErrorControllerTargetClassPostProcessor@6522}
//2 = {AopAutoConfiguration$ClassProxyingConfiguration$lambda@6523}
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
//循環獲取並進行調用,此處第一次調用
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
}
CachingMetadataReaderFactoryPostProcessor
調用CachingMetadataReaderFactoryPostProcessor的postProcessBeanDefinitionRegistry,方法內部調用register方法;
具體來說,CachingMetadataReaderFactoryPostProcessor注冊了一個internalCachingMetadataReaderFactory類型的beanDefinition,
同時給internalConfigurationAnnotationProcessor的BeanDefinition的pv添加了一個key為metadataReaderFactory,value = RuntimeBeanReference,name=internalCachingMetadataReaderFactory的屬性值
class SharedMetadataReaderFactoryContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {
public static final String BEAN_NAME = "org.springframework.boot.autoconfigure."
+ "internalCachingMetadataReaderFactory";
static class CachingMetadataReaderFactoryPostProcessor
implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//注冊bean
register(registry);
//配置后處理
configureConfigurationClassPostProcessor(registry);
}
private void register(BeanDefinitionRegistry registry) {
//此方法生成了一個普通BeanDefinition,並設置了BeanDefinition中class= SharedMetadataReaderFactoryBean,supplier = SharedMetadataReaderFactoryBean::new
BeanDefinition definition = BeanDefinitionBuilder
.genericBeanDefinition(SharedMetadataReaderFactoryBean.class, SharedMetadataReaderFactoryBean::new)
.getBeanDefinition();
//將生成的beanDefinition注冊到了容器中
registry.registerBeanDefinition(BEAN_NAME, definition);
}
private void configureConfigurationClassPostProcessor(BeanDefinitionRegistry registry) {
try {
configureConfigurationClassPostProcessor(
registry.getBeanDefinition(AnnotationConfigUtils.CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
catch (NoSuchBeanDefinitionException ex) {
}
}
//此時的definition 的beabClass=org.springframework.context.annotation.ConfigurationClassPostProcessor
private void configureConfigurationClassPostProcessor(BeanDefinition definition) {
if (definition instanceof AbstractBeanDefinition) {
configureConfigurationClassPostProcessor((AbstractBeanDefinition) definition);
return;
}
configureConfigurationClassPostProcessor(definition.getPropertyValues());
}
private void configureConfigurationClassPostProcessor(AbstractBeanDefinition definition) {
//首先獲取回調函數instanceSupplier ,此時instanceSupplier = null;否則根據提供的函數生成一個
//ConfigurationClassPostProcessorCustomizingSupplier對象
Supplier<?> instanceSupplier = definition.getInstanceSupplier();
if (instanceSupplier != null) {
definition.setInstanceSupplier(
new ConfigurationClassPostProcessorCustomizingSupplier(this.context, instanceSupplier));
return;
}
configureConfigurationClassPostProcessor(definition.getPropertyValues());
}
private void configureConfigurationClassPostProcessor(MutablePropertyValues propertyValues) {
//此時的propertyValues為空,添加了一個運行時Bean引用 = internalCachingMetadataReaderFactory
propertyValues.add("metadataReaderFactory", new RuntimeBeanReference(BEAN_NAME));
}
}
}
internalConfigurationAnnotationProcessor beanDefinition是何時注冊的?
- AnnotationConfigUtils
public abstract class AnnotationConfigUtils {
//內部托管的Configuration注釋處理器的bean名。
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
}
ConfigurationWarningsPostProcessor
此方法根據注解類來解析包路徑,如果沒有提供包路徑,則根據注解類生成默認掃描包路徑。同時對包路徑進行錯誤性檢查
public class ConfigurationWarningsApplicationContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
protected static final class ConfigurationWarningsPostProcessor
implements PriorityOrdered, BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//對checks進行校驗,此時checks.length = 1,checks[0]=ComponentScanPackageCheck
for (Check check : this.checks) {
String message = check.getWarning(registry);
if (StringUtils.hasLength(message)) {
warn(message);
}
}
}
}
//檢查問題包上的@ComponentScan。
protected static class ComponentScanPackageCheck implements Check {
private static final Set<String> PROBLEM_PACKAGES;
static {
Set<String> packages = new HashSet<>();
packages.add("org.springframework");
packages.add("org");
PROBLEM_PACKAGES = Collections.unmodifiableSet(packages);
}
static {
Set<String> packages = new HashSet<>();
packages.add("org.springframework");
packages.add("org");
PROBLEM_PACKAGES = Collections.unmodifiableSet(packages);
}
@Override
public String getWarning(BeanDefinitionRegistry registry) {
Set<String> scannedPackages = getComponentScanningPackages(registry);
//拿到包路徑之后,獲取有問題的包路徑
List<String> problematicPackages = getProblematicPackages(scannedPackages);
if (problematicPackages.isEmpty()) {
return null;
}
return "Your ApplicationContext is unlikely to start due to a @ComponentScan of "
+ StringUtils.collectionToDelimitedString(problematicPackages, ", ") + ".";
}
protected Set<String> getComponentScanningPackages(BeanDefinitionRegistry registry) {
Set<String> packages = new LinkedHashSet<>();
//此時names =
//0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
//1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
//2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
//3 = "org.springframework.context.event.internalEventListenerProcessor"
//4 = "org.springframework.context.event.internalEventListenerFactory"
//5 = "userProviderBootstrap"
//6 = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"
String[] names = registry.getBeanDefinitionNames();
for (String name : names) {
//循環對BeanDefinition進行判斷,如果是注解型BeanDefinition,則進行處理,此時滿足條件的BeanDefinition為userProviderBootstrap
BeanDefinition definition = registry.getBeanDefinition(name);
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedDefinition = (AnnotatedBeanDefinition) definition;
//根據掃描到的注解beanDefinition解析類上標注的掃描包
addComponentScanningPackages(packages, annotatedDefinition.getMetadata());
}
}
return packages;
}
//傳入掃描包變量,根據注解元信息進行判斷
private void addComponentScanningPackages(Set<String> packages, AnnotationMetadata metadata) {
//獲取到注解上的所有屬性 basePackageClasses、basePackages、excludeFilters、includeFilters
//lazyInit、nameGenerator、resourcePattern、scopeResolver、scopedProxy、useDefaultFilters、value
AnnotationAttributes attributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(ComponentScan.class.getName(), true));
if (attributes != null) {
addPackages(packages, attributes.getStringArray("value"));
addPackages(packages, attributes.getStringArray("basePackages"));
addClasses(packages, attributes.getStringArray("basePackageClasses"));
if (packages.isEmpty()) {
//此時packages為空,添加默認包路徑com.bail.user.service
packages.add(ClassUtils.getPackageName(metadata.getClassName()));
}
}
}
private boolean isProblematicPackage(String scannedPackage) {
if (scannedPackage == null || scannedPackage.isEmpty()) {
return true;
}
//默認的PROBLEM_PACKAGES有兩個路徑:org.springframework、org
return PROBLEM_PACKAGES.contains(scannedPackage);
}
}
}
isProblematicPackage此處的方法命名和返回值有歧義
getBeanNamesForType
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
//此處參數為BeanDefinitionRegistryPostProcessor.class ,true,false
private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
List<String> result = new ArrayList<>();
// Check all bean definitions.
for (String beanName : this.beanDefinitionNames) {
// Only consider bean as eligible if the bean name is not defined as alias for some other bean.
if (!isAlias(beanName)) {
try {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// Only check bean definition if it is complete.
if (!mbd.isAbstract() && (allowEagerInit ||
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
boolean isFactoryBean = isFactoryBean(beanName, mbd);
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
boolean matchFound = false;
boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());
if (!isFactoryBean) {
if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
else {
if (includeNonSingletons || isNonLazyDecorated ||
(allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
if (!matchFound) {
// In case of FactoryBean, try to match FactoryBean instance itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
}
}
if (matchFound) {
result.add(beanName);
}
}
}
catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {
if (allowEagerInit) {
throw ex;
}
// Probably a placeholder: let's ignore it for type matching purposes.
LogMessage message = (ex instanceof CannotLoadBeanClassException ?
LogMessage.format("Ignoring bean class loading failure for bean '%s'", beanName) :
LogMessage.format("Ignoring unresolvable metadata in bean definition '%s'", beanName));
logger.trace(message, ex);
// Register exception, in case the bean was accidentally unresolvable.
onSuppressedException(ex);
}
catch (NoSuchBeanDefinitionException ex) {
// Bean definition got removed while we were iterating -> ignore.
}
}
}
// Check manually registered singletons too.
for (String beanName : this.manualSingletonNames) {
try {
// In case of FactoryBean, match object created by FactoryBean.
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// In case of FactoryBean, try to match FactoryBean itself next.
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
if (isTypeMatch(beanName, type)) {
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
// Shouldn't happen - probably a result of circular reference resolution...
logger.trace(LogMessage.format(
"Failed to check manually registered singleton with name '%s'", beanName), ex);
}
}
return StringUtils.toStringArray(result);
}
}
ConfigurationClassPostProcessor
processConfigBeanDefinitions方法中,已注冊的beanDefinitions:
0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
1 = "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
2 = "org.springframework.context.annotation.internalCommonAnnotationProcessor"
3 = "org.springframework.context.event.internalEventListenerProcessor"
4 = "org.springframework.context.event.internalEventListenerFactory"
5 = "userProviderBootstrap"
6 = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory"
經過parser.parse(candidates)方法的處理,將自動導入的類從SpringFactory加載到了ConfigurationClassParser 的ConfigurationClasses容器中。
隨后調用ConfigurationClassBeanDefinitionReader 對ConfigurationClasses進行BeanDefinition加載
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {
private ConfigurationClassBeanDefinitionReader reader;
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
//基於configuration類的注冊表構建並驗證配置模型。
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//聲明的配置候選項
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//從工廠中獲取候選項名稱
String[] candidateNames = registry.getBeanDefinitionNames();
//for循環執行完畢,符合配置候選類的BeanDefinition只有UserProviderBootstrap 一個
for (String beanName : candidateNames) {
//獲得ConfigurationClassPostProcessor 的BeanDefinition,pv包含一個metadataReaderFactory
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//獲取的對應的屬性為空
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//UserProviderBootstrap BeanDefinition符合條件,加入配置候選類集合
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
//檢測通過外圍應用程序上下文提供的任何自定義bean名稱生成策略
SingletonBeanRegistry sbr = null;
//BeanFactory 符合SingletonBeanRegistry
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
//此處獲取的generator 為空
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();
}
// Parse each @Configuration class
//此處構造一個配置類解析器,用來解析配置候選類
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//使用set集合去重
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
//調用解析器進行解析
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(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);
//此處經過加載,BeanDefinitionMap中含有152個BeanDefinition
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
//至此,根據首要類加載的BeanDefinition解析完畢,包括自動裝配類
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
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());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
//將ImportRegistry注冊為一個bean,以便支持importtaware @Configuration類
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
//准備在運行時服務bean請求的Configuration類,將它們替換為cglib增強的子類。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
//添加一個Bean類型的后置處理器 ImportAwareBeanPostProcessor
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
}
- ConfigurationClassUtils
abstract class ConfigurationClassUtils {
public static final String CONFIGURATION_CLASS_FULL = "full";
public static final String CONFIGURATION_CLASS_LITE = "lite";
public static final String CONFIGURATION_CLASS_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "configurationClass");
private static final String ORDER_ATTRIBUTE =
Conventions.getQualifiedAttributeName(ConfigurationClassPostProcessor.class, "order");
private static final Log logger = LogFactory.getLog(ConfigurationClassUtils.class);
//候選指標
private static final Set<String> candidateIndicators = new HashSet<>(8);
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
//className = org.springframework.context.annotation.ConfigurationClassPostProcessor
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
AnnotationMetadata metadata;
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
//是否可以重用給定BeanDefinition中預解析的元數據
//userProviderBootstrap BeanDefinition進入此處
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
//ConfigurationClassPostProcessor符合else if 判斷
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
//ConfigurationClassPostProcessor 符合BeanFactoryPostProcessor,返回false
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
//SharedMetadataReaderFactoryBean進入此處
metadata = AnnotationMetadata.introspect(beanClass);
}
else {
try {
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
metadata = metadataReader.getAnnotationMetadata();
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
}
//userProviderBootstrap 得到的config = "proxyBeanMethods" -> {Boolean@5288} true;"value" -> ""
//SharedMetadataReaderFactoryBean 得到config = null;
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
//為當前userProviderBootstrap BeanDefinition設置屬性:***.configurationClass
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
return false;
}
// It's a full or lite configuration candidate... Let's determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
}
ConfigurationClassParser.parse()
當ConfigurationClassParser對首要類UserProviderBootstrap解析完畢之后,主要做了以下工作:
1、獲取當前類的內部類,並對內部類符合配置類定義的類添加到緩存容器並進行處理,主要是處理標注了@Component及其派生類的類
2、加載配置類上導入的外部屬性資源@PropertySource
2、解析當前類上標注了@ComponentScan的資源,使用類路徑加載器解析配置類,並循環調用當前方法進行配置類的解析
3、解析@Import注解導入的類,主要在當前容器中加入了注解器和在當前解析類ConfigurationClassParser 的容器中,添加了導入包處理器ImportHandler
4、解析由ImportResource引入的資源類
5、處理由@Bean注解注冊的BeanDefinition,添加到了配置類中的BeanMethod緩存中
6、最后處理接口(默認實現方法)和父類中的一些方法
解析完的相關信息,存儲在ConfigurationClass中,同時解析到的BeanDefinition存儲到了Map中,
調用完ConfigurationClassParser的parse方法后,開始調用deferredImportSelectorHandler 的process方法
/**
*解析一個{@link Configuration}類定義,填充一組{@link ConfigurationClass}對象(解析單個Configuration類可能會
*導致任意數量的ConfigurationClass對象,因為一個Configuration類可能會使用{@link import}注釋導入另一個Configuration類)。
*
*/
class ConfigurationClassParser {
private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//userProviderBootstrap BeanDefinition進入此處
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);
}
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
//配置類集合
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
//遞歸地處理配置類及其超類層次結構,此處得到的sourceClass = UserProviderBootstrap
//因為配置類可能存在層級,因此該循環是針對配置類的父類進行的,但是配置類對象是不會變的
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
//工廠方法從{@link ConfigurationClass}中獲取{@link SourceClass}
private SourceClass asSourceClass(ConfigurationClass configurationClass, Predicate<String> filter) throws IOException {
AnnotationMetadata metadata = configurationClass.getMetadata();
if (metadata instanceof StandardAnnotationMetadata) {
return asSourceClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass(), filter);
}
return asSourceClass(metadata.getClassName(), filter);
}
//工廠方法從{@link Class}中獲取{@link SourceClass}。
SourceClass asSourceClass(@Nullable Class<?> classType, Predicate<String> filter) throws IOException {
if (classType == null || filter.test(classType.getName())) {
return this.objectSourceClass;
}
try {
// Sanity test that we can reflectively read annotations,
// including Class attributes; if not -> fall back to ASM
for (Annotation ann : classType.getDeclaredAnnotations()) {
AnnotationUtils.validateAnnotation(ann);
}
return new SourceClass(classType);
}
catch (Throwable ex) {
// Enforce ASM via class name resolution
return asSourceClass(classType.getName(), filter);
}
}
}
doProcessConfigurationClass 處理ConfigurationClass
class ConfigurationClassParser {
private final ComponentScanAnnotationParser componentScanParser;
/*
*configClass: userProviderBootstrap
*sourceClass: UserProviderBootstrap
*
*/
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
//判斷UserProviderBootstrap類上有Component注解,進行解析,因為該配置類中被@Component注解的
//bean可能也是配置類
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
//解析@PropertySources注解,該注解的作用便是引入額外的properties,文件解析過后再將文件屬性值
//注入到environment中,如果有相同的則替換新的,在某個配置上配置的屬性文件,在屬性導入后,在其他配置上也可以使用
//同時,@PropertySource 和 @ConfigurationProperties注解配合使用,可以將屬性文件與一個java類綁定,將
//屬性文件中的變量值注入到該Java類的成員變量中。
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//通過ComponentScan掃描到的BeanDefinition,會經過parse方法進行解析,最終還會調到此方法內,直到標注ComponentScan的類解析完畢
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
//隨后進行@Import注解的解析,此過程只是單純的添加了一個ImportSelectorHolder
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
// 解析到帶@Bean注解的方法,然后封裝BeanMethod方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 處理接口上的默認的實現方法
processInterfaces(configClass, sourceClass);
// Process superclass, if any 處理超類
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
}
processMemberClasses 獲取配置類的嵌套內部類
class ConfigurationClassParser {
//注冊恰好是配置類本身的成員(嵌套)類
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
Predicate<String> filter) throws IOException {
//獲取配置類的嵌套內部類
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
//如果嵌套內部類存在
if (!memberClasses.isEmpty()) {
//創建指定大小的內部類集合
List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
for (SourceClass memberClass : memberClasses) {
//驗證嵌套類是否是配置類(即:通過@Configuration、@Component、@Bean等注解標注)
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
//對嵌套內部類進行排序
OrderComparator.sort(candidates);
for (SourceClass candidate : candidates) {
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//使用遞歸的方式將嵌套內部類當成普通的類來處理
processConfigurationClass(candidate.asConfigClass(configClass), filter);
}
finally {
this.importStack.pop();
}
}
}
}
}
}
- getMemberClasses
上述處理嵌套內部類還有一個比較核心的方法getMemberClasses,此方法獲取配置類的嵌套內部類:
class ConfigurationClassParser {
private class SourceClass implements Ordered {
public Collection<SourceClass> getMemberClasses() throws IOException {
Object sourceToProcess = this.source;
if (sourceToProcess instanceof Class) {
Class<?> sourceClass = (Class<?>) sourceToProcess;
try {
Class<?>[] declaredClasses = sourceClass.getDeclaredClasses();
List<SourceClass> members = new ArrayList<>(declaredClasses.length);
for (Class<?> declaredClass : declaredClasses) {
members.add(asSourceClass(declaredClass, DEFAULT_EXCLUSION_FILTER));
}
return members;
}
catch (NoClassDefFoundError err) {
// getDeclaredClasses() failed because of non-resolvable dependencies
// -> fall back to ASM below
sourceToProcess = metadataReaderFactory.getMetadataReader(sourceClass.getName());
}
}
// ASM-based resolution - safe for non-resolvable classes as well
//基於ASM的解析,對於不可以解析的類也是安全的
MetadataReader sourceReader = (MetadataReader) sourceToProcess;
// 獲取配置類的嵌套內部類
String[] memberClassNames = sourceReader.getClassMetadata().getMemberClassNames();
List<SourceClass> members = new ArrayList<>(memberClassNames.length);
for (String memberClassName : memberClassNames) {
try {
//將嵌套類轉換成簡單的包裝類,並且經過默認過濾器的過濾
members.add(asSourceClass(memberClassName, DEFAULT_EXCLUSION_FILTER));
}
catch (IOException ex) {
// Let's skip it if it's not resolvable - we're just looking for candidates
if (logger.isDebugEnabled()) {
logger.debug("Failed to resolve member class [" + memberClassName +
"] - not considering it as a configuration class candidate");
}
}
}
return members;
}
}
}
componentScanParser.parse 解析componentScan注解
調用ComponentScanAnnotationParser 掃描包注解的解析器,方法內部定義了一個類路徑掃描器,隨后解析了注解上的一些屬性,包括范圍域、資源類型(.class)、是否懶加載、包路徑加載、過濾器,隨后調用Scanner的doScan方法,即ClassPathBeanDefinitionScanner 注冊BeanDefinition的方法
class ComponentScanAnnotationParser {
private final Environment environment;
private final ResourceLoader resourceLoader;
private final BeanNameGenerator beanNameGenerator;
private final BeanDefinitionRegistry registry;
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
//解析包路徑,如果包路徑為空,則以當前類所在的包為根路徑
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
processImports
getImports得到的兩個Import注解引入的類:AutoConfigurationImportSelector、AutoConfigurationPackages.Registrar,然后對兩個導入候選類進行判斷,對配置類進行判斷,如果不是循環導入和 是在堆棧上鏈式導入,進行下一步解析;首先將配置類入棧,對導入候選類進行遍歷循環處理。首先對AutoConfigurationPackages.Registrar類進行處理,符合 else if 判斷,即instance of ImportBeanDefinitionRegistrar,符合導入BeanDefinition注冊;隨后對AutoConfigurationImportSelector進行解析,在對AutoConfigurationImportSelector進行解析的時候,由於符合invokeAwareMethods方法中的類型判斷,所以進行包裝處理,並返回實例對象。
class ConfigurationClassParser {
private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();
/**
* Returns {@code @Import} class, considering all meta-annotations.
*/
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
Set<SourceClass> imports = new LinkedHashSet<>();
Set<SourceClass> visited = new LinkedHashSet<>();
collectImports(sourceClass, imports, visited);
return imports;
}
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
//獲取排除類過濾器
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
//符合延遲導入選擇器,調用對應的handler進行處理,handler是在類初始化的時候,進行創建的
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
//candidateClass = AutoConfigurationPackages.Registrar,此處返回該類的實例對象
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
//隨后將當前類配置為配置類的導入注冊器ImportBeanDefinitionRegistrar,調用的是ConfigurationClass的方法
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
}
*ConfiguraitonClass
/**
*表示用戶定義的{@link Configuration @Configuration}類。<p>包含一組{@link Bean}方法,
*包括在類的祖先中定義的所有此類方法,以“扁平化”的方式。
*/
final class ConfigurationClass {
@Nullable
private String beanName;
private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
private final Map<String, Class<? extends BeanDefinitionReader>> importedResources =
new LinkedHashMap<>();
private final Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> importBeanDefinitionRegistrars =
new LinkedHashMap<>();
void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, AnnotationMetadata importingClassMetadata) {
this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);
}
}
*invokeAwareMethods
abstract class ParserStrategyUtils {
private static void invokeAwareMethods(Object parserStrategyBean, Environment environment,
ResourceLoader resourceLoader, BeanDefinitionRegistry registry, @Nullable ClassLoader classLoader) {
if (parserStrategyBean instanceof Aware) {
if (parserStrategyBean instanceof BeanClassLoaderAware && classLoader != null) {
((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader);
}
if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) {
((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry);
}
if (parserStrategyBean instanceof EnvironmentAware) {
((EnvironmentAware) parserStrategyBean).setEnvironment(environment);
}
if (parserStrategyBean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader);
}
}
}
}
deferredImportSelectorHandler.process()導入選擇器的處理器
參考DeferredImportSelectorHandler
ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(configClasses)
此方法對configClasses類進行解析,包括注冊類中的BeanMethod、ImportedResources等
class ConfigurationClassBeanDefinitionReader {
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
//將configClass注冊為一個AnnotationBeanDefinition
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
//獲取配置類中的BeanMethod,並進行BeanDefinition注冊
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//獲取配置類中的ImportedResources進行加載
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//從注冊器中獲取需要注冊的BeanDefinitions
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isTraceEnabled()) {
logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
}
}
}
ConfigurationClassParser.DeferredImportSelectorHandler 導入包處理
此方法對接上文中processImports 中AutoConfigurationImportSelector類的處理.DeferredImportSelectorHandler是ConfigurationClassParser的一個內部類。
在處理完configurationClass方法后,開始調用process方法對導入類進行處理,process方法中構建了一個GroupingHandler,調用了GroupingHandler的register方法循環對ImportSector進行處理,首先調用注冊方法,隨后調用handler.processGroupImports()方法。
class ConfigurationClassParser {
private class DeferredImportSelectorHandler {
private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();
/**
* 處理指定的{@link DeferredImportSelector}。如果正在收集遞延的import *選擇器,這將把該實例注冊到列表中。
* 如果它們正在被處理,{@link DeferredImportSelector}
* 也會根據其{@link DeferredImportSelector. group}立即被處理。
* @param configClass the source configuration class
* @param importSelector the selector to handle
*/
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
//根據配置類和過濾器配置一個延遲導入選擇器holder
DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
if (this.deferredImportSelectors == null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
handler.register(holder);
handler.processGroupImports();
}
else {
//將當期holder添加到容器中
this.deferredImportSelectors.add(holder);
}
}
public void process() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}
}
private static class DeferredImportSelectorHolder {
private final ConfigurationClass configurationClass;
private final DeferredImportSelector importSelector;
public DeferredImportSelectorHolder(ConfigurationClass configClass, DeferredImportSelector selector) {
this.configurationClass = configClass;
this.importSelector = selector;
}
public ConfigurationClass getConfigurationClass() {
return this.configurationClass;
}
public DeferredImportSelector getImportSelector() {
return this.importSelector;
}
}
}
AutoConfigurationImportSelector
getAutoConfigurationEntry方法首先根據注解類獲取屬性值,此處提供了一個EnableAutoConfiguration的注解返回值
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//返回了注解內的兩個屬性值 exclude、excludeName
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//然后根據過濾器加載配置類,此處從SpringFactory加載了132個工廠類
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//getConfigurationClassFilter()從SpringFactory加載類導入過濾器,然后對configurations進行過濾,然后剩下25個
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClass().getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
+ " annotated with " + ClassUtils.getShortName(name) + "?");
return attributes;
}
/**
* Return the source annotation class used by the selector.
* @return the annotation class
*/
protected Class<?> getAnnotationClass() {
return EnableAutoConfiguration.class;
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
//getSpringFactoriesLoaderFactoryClass方法返回的EnableAutoConfiguration
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
}
ConfigurationClassParser.DeferredImportSelectorGroupingHandler
process方法中對 DeferredImportSelectorHolder 進行注冊,此處得到的group為:AutoConfigurationImportSelector.AutoConfigurationGroup自動配置組,在createGroup(group)方法中,AutoConfigurationGroup繼承了多個接口,在執行實例化的方法過程中,對AutoConfigurationGroup對象進行了包裝處理,給多個成員屬性賦值,方便工廠、資源的獲取。並將實例化的對象包裝成DeferredImportSelectorGrouping。
調用GroupingHandler的processGroupImports方法,方法內部調用了DeferredImportSelectorGrouping的getCandidateFilter方法獲取候選類過濾器,調用DeferredImportSelectorGrouping的getImports方法獲取導入類,getImport方法內部調用AutoConfigurationGroup的process方法。此方法從SpringFactory工廠中加載到25個ConfigurationClass,使用OnClassCondition、OnBeanCondition、OnWebApplicationCondition經過過濾。
0 = {DeferredImportSelector$Group$Entry@5447} "org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration"
1 = {DeferredImportSelector$Group$Entry@5448} "org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration"
2 = {DeferredImportSelector$Group$Entry@5449} "org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration"
3 = {DeferredImportSelector$Group$Entry@5450} "org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration"
4 = {DeferredImportSelector$Group$Entry@5451} "org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration"
5 = {DeferredImportSelector$Group$Entry@5452} "org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration"
6 = {DeferredImportSelector$Group$Entry@5453} "org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration"
7 = {DeferredImportSelector$Group$Entry@5454} "org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration"
8 = {DeferredImportSelector$Group$Entry@5455} "com.alibaba.boot.dubbo.autoconfigure.DubboAutoConfiguration"
9 = {DeferredImportSelector$Group$Entry@5456} "org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration"
10 = {DeferredImportSelector$Group$Entry@5457} "org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration"
11 = {DeferredImportSelector$Group$Entry@5458} "org.springframework.boot.autoconfigure.aop.AopAutoConfiguration"
12 = {DeferredImportSelector$Group$Entry@5459} "org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration"
13 = {DeferredImportSelector$Group$Entry@5460} "org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration"
14 = {DeferredImportSelector$Group$Entry@5461} "org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration"
15 = {DeferredImportSelector$Group$Entry@5462} "org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration"
16 = {DeferredImportSelector$Group$Entry@5463} "org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration"
17 = {DeferredImportSelector$Group$Entry@5464} "org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration"
18 = {DeferredImportSelector$Group$Entry@5465} "org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration"
19 = {DeferredImportSelector$Group$Entry@5466} "org.springframework.boot.autoconfigure.sql.init.SqlInitializationAutoConfiguration"
20 = {DeferredImportSelector$Group$Entry@5467} "org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration"
21 = {DeferredImportSelector$Group$Entry@5468} "org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration"
22 = {DeferredImportSelector$Group$Entry@5469} "org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration"
23 = {DeferredImportSelector$Group$Entry@5470} "org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration"
24 = {DeferredImportSelector$Group$Entry@5471} "org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration"
然后繼續調用processImports()對configurationClass進行處理,我們查看ConfigurationClassParser.processImports對configurationClass的處理
class ConfigurationClassParser {
private class DeferredImportSelectorGroupingHandler {
private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
public void register(DeferredImportSelectorHolder deferredImport) {
//加載類型
Class<? extends Group> group = deferredImport.getImportSelector().getImportGroup();
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));
//添加實例
grouping.add(deferredImport);
//此處解析到的configurationClass為:com.bail.user.service.UserProviderBootstrap
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());
}
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
Predicate<String> exclusionFilter = grouping.getCandidateFilter();
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
exclusionFilter, false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
}
});
}
}
private Group createGroup(@Nullable Class<? extends Group> type) {
Class<? extends Group> effectiveType = (type != null ? type : DefaultDeferredImportSelectorGroup.class);
return ParserStrategyUtils.instantiateClass(effectiveType, Group.class,
ConfigurationClassParser.this.environment,
ConfigurationClassParser.this.resourceLoader,
ConfigurationClassParser.this.registry);
}
}
}
AutoConfigurationImportSelector.AutoConfigurationGroup
process方法內部調用AutoConfigurationImportSelector的getAutoConfigurationEntry方法
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
private static class AutoConfigurationGroup
implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(annotationMetadata);
this.autoConfigurationEntries.add(autoConfigurationEntry);
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
}
}
ConfigurationClassParser.DeferredImportSelectorGrouping
class ConfigurationClassParser {
private static final Predicate<String> DEFAULT_EXCLUSION_FILTER = className ->
(className.startsWith("java.lang.annotation.") || className.startsWith("org.springframework.stereotype."));
private static class DeferredImportSelectorGrouping {
private final DeferredImportSelector.Group group;
private final List<DeferredImportSelectorHolder> deferredImports = new ArrayList<>();
DeferredImportSelectorGrouping(Group group) {
this.group = group;
}
public void add(DeferredImportSelectorHolder deferredImport) {
this.deferredImports.add(deferredImport);
}
/**
* Return the imports defined by the group.
* @return each import with its associated configuration class
*/
public Iterable<Group.Entry> getImports() {
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
return this.group.selectImports();
}
public Predicate<String> getCandidateFilter() {
Predicate<String> mergedFilter = DEFAULT_EXCLUSION_FILTER;
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
Predicate<String> selectorFilter = deferredImport.getImportSelector().getExclusionFilter();
if (selectorFilter != null) {
mergedFilter = mergedFilter.or(selectorFilter);
}
}
return mergedFilter;
}
}
}
ConfigurationClassParser.processImports
此處我們以MessageSourceAutoConfiguration為例,此處方法中configClass = com.bail.user.service.UserProviderBootstrap、
importCandidates為MessageSourceAutoConfiguration,將MessageSourceAutoConfiguration包裝成ConfigurationClass,並進行處理。
class ConfigurationClassParser {
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
//此處對於導入類有三種類型的處理,MessageSourceAutoConfiguration是一個普通配置類
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
//不是ImportSelector 和ImportBeanDefinitionRegistrar ,當做Configuration class進行處理,com.bail.user.service.UserProviderBootstrap -> MessageSourceAutoConfiguration
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
}
PropertySourcesPlaceholderConfigurer
屬性占位符后置處理器,注入了屬性源
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
this.propertySources.addLast(
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
@Nullable
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
try {
PropertySource<?> localPropertySource =
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
}
else {
this.propertySources.addLast(localPropertySource);
}
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
}
BeanFactoryPostProcessor層級
/**
*工廠鈎子,允許自定義修改應用程序上下文的bean定義,調整上下文的底層bean工廠的bean屬性值.
*
*適用於針對覆蓋在應用程序上下文中配置的bean屬性的系統管理員的自定義配置文件。
*請參閱PropertyResourceConfigurer及其具體實現,了解解決此類配置需求的開箱即用的解決方案。
*
*BeanFactoryPostProcessor可以與bean定義交互並修改它們,但不能與bean實例交互。
*樣做可能會導致過早的bean實例化,違反容器並導致意外的副作用。 如果需要bean實例交互,則考慮實現BeanPostProcessor。
*
*ApplicationContext在其bean定義中自動檢測BeanFactoryPostProcessor bean,並在創建任何其他bean之前應用它們。
*BeanFactoryPostProcessor也可以用ConfigurableApplicationContext編程注冊。
*
*在ApplicationContext中被自動檢測到的BeanFactoryPostProcessor bean將根據 priorityorordered和Ordered語義進行排序。
*相反,用ConfigurableApplicationContext編程注冊的BeanFactoryPostProcessor bean將按照注冊的順序應用;
*通過實現prioritorderordered或Ordered接口表示的任何排序語義將被編程注冊的后處理程序忽略。
*此外,對於BeanFactoryPostProcessor bean, @Order注釋不被考慮。
*/
@FunctionalInterface
public interface BeanFactoryPostProcessor {
/**
*在標准初始化之后修改應用程序上下文的內部bean工廠。 將加載所有bean定義,但還沒有實例化任何bean。
*這允許覆蓋或添加屬性,甚至可以添加到急於初始化的bean。
* 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 overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor
/**
*擴展到標准BeanFactoryPostProcessor SPI,允許在常規BeanFactoryPostProcessor檢測開始之前注冊更多的bean定義。
*特別是,BeanDefinitionRegistryPostProcessor可以注冊進一步的bean定義,這些bean定義依次定義BeanFactoryPostProcessor實例。
*
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
*在標准初始化之后修改應用程序上下文的內部bean定義注冊表。
*將加載所有常規bean定義,但還沒有實例化任何bean。這允許在下一個后處理階段開始之前添加進一步的bean定義。
*
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}