前言
关于@Import注解的使用,在Spring源码中随处可见,其作用大家基本也都知道,无非就是注入指定的Bean到Spring IOC容器管理,只能作用用于类上,其用法分三种:普通的类直接注入、实现了ImportSelector接口的类、实现了ImportBeanDefinitionRegistrar接口的类,那么Spring具体是如何实现的?这三种方式又有何不同?一起跟进源码一探究竟,彻底了解Import的实现。
源码追踪(Spring版本:5.3.6-SNAPSHOT)
众所周知Spring需要先初始化上下文容器,Spring上下文容器针对不同的场景设计了较多类型,不过都大同小异,这里拿其中的AnnotationConfigApplicationContext进行讲解,如果需要进一步了解Spring的每一个容器或者Spring的更多源码细节,可关注我,我会在后面的章节中逐步揭开Spring源码迷雾。
您的认可是我前进的动力,如果您觉得可以请关注我并转发文章,谢谢!!!
AnnotationConfigApplicationContext(AbstractApplicationContext)
public AnnotationConfigApplicationContext(Class>... componentClasses) {
// 注解配置上下文初始化
this();
// 将配置组件(AppConfig)注册到AnnotationConfigApplicationContext上下文对象的beanFactory中(即将bean信息放入beanDefinitionMap中)
register(componentClasses);
// 刷新注册到AnnotationConfigApplicationContext上下文对象的相关属性
refresh();
}
@Override
// AbstractApplicationContext公共方法
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// 刷新AnnotationConfigApplicationContext上下文对象的BeanFactory并返回BeanFactory对象
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 实例化并调用所有已注册的BeanFactoryPostProcessor的Bean到Spring容器中.
invokeBeanFactoryPostProcessors(beanFactory);
......
// 实例化所有BeanFactory中非延迟加载的Bean.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
......
}
PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List
beanFactoryPostProcessors) { ......
// 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.
List
currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 获取BeanDefinitionRegistryPostProcessor类型的bean名称,注意这里获取到了名字为
// org.springframework.context.annotation.internalConfigurationAnnotationProcessor的bean
// (这个bean不是直接存在的,在AnnotationConfigUtils类中可查到其对应的Ben为ConfigurationClassPostProcessor)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)获取到ConfigurationClassPostProcessor
// 将ConfigurationClassPostProcessor添加到当前注册Bean的处理对象集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 将BeanDefinitionRegistryPostProcessor排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 将BeanDefinitionRegistryPostProcessor稍后注册到BeanFactory
registryProcessors.addAll(currentRegistryProcessors);
//
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
......
}
通过调用PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors方法循环执行所有BeanDefinitionRegistryPostProcessor,将相关Bean注入BeanFacotry。这里通过调用ConfigurationClassPostProcessor 处理所有@Configuration配置类,其通过核心方法processConfigBeanDefinitions来处理相关Bean的注入。
ConfigurationClassPostProcessor
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 生成处理ID
int factoryId = System.identityHashCode(beanFactory);
// 判断后置处理器在registriesPostProcessed和factoriesPostProcessed中有没有被调用过
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
// 调用前保存factoryId,防止被重复调用
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// 注入标有@configuration的Bean里面需要注入的类(如:@Import注解)
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 需要处理的候选@configuration类
List
configCandidates = new ArrayList<>(); // 获取BeanFactory中注入的所有beanDefinitionNames
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// 检查当前Bean是否已当作配置类处理过
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
// 检查当前Bean是否是配置类,如果是则添加到configCandidates中,后面进行处理
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
......
// 准备解析 @Configuration 标注的类,构建解析对象
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 配置Bean去重
Set
candidates = new LinkedHashSet<>(configCandidates); // 存储已解析过的配置类
Set
alreadyParsed = new HashSet<>(configCandidates.size()); // 循环解析
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
// 解析所有@Configuration标记Bean,并将解析的Bean信息存入ConfigurationClassParser的configurationClasses集合中
parser.parse(candidates);
parser.validate();
Set
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());
}
// 初始化所有配置类中的Bean(包含处理ImportBeanDefinitionRegistrars类),
// 并将其放入Spring容器中(BeanFactory的beanDefinitionMap)
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
......
}
while (!candidates.isEmpty());
......
}
通过调用ConfigurationClassParser#parse对@Configuration类进行解析。
ConfigurationClassParser
public void parse(Set
configCandidates) { for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
// Configuration类为AnnotatedBean
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());
}
}
......
}
this.deferredImportSelectorHandler.process();
}
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate
filter) throws IOException { // 判断是否需要跳过该配置类的解析(例如配置了@Conditional注解)
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 标识该配置类是否解析过
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
......
// Recursively process the configuration class and its superclass hierarchy.
// 将配置类转为SourceClass类
SourceClass sourceClass = asSourceClass(configClass, filter);
// 从当前配置类configClass开始向上沿着类继承结构逐层执行doProcessConfigurationClass,
// 直到遇到的父类是由Java提供的类结束循环
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate
filter) throws IOException {
// Component注解存在继承关系,递归处理嵌套类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
......
// 重点来了,在这里处理Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
......
// 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;
}
/**
* 处理配置类上搜集到的@Import注解
* @Param configuClass 配置类
* @Param currentSourceClass 当前源码类
* @Param importCandidates 所有的@Import注解的value
* @Param exclusionFilter 需要排除的类
* @Param checkForCircularImports 是否检查循环导入
**/
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection
importCandidates, Predicate exclusionFilter, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
// 开始处理配置类configClass上@Import所有的importCandidates
this.importStack.push(configClass);
try {
// 循环处理每一个@Import,每个@Import可能导入三种类型的类 :
// 1. ImportSelector
// 2. ImportBeanDefinitionRegistrar
// 3. 其他类型,都当作配置类处理,也就是相当于使用了注解@Configuration的配置类
// 下面的for循环中对这三种情况执行了不同的处理逻辑
for (SourceClass candidate : importCandidates) {
// 处理ImportSelector类(Spring Boot的自动装配采用的是这种方式)
if (candidate.isAssignable(ImportSelector.class)) {
// 加载对应的ImportSelector实现类
Class> candidateClass = candidate.loadClass();
// 实例化对应的实现ImportSelector的类
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
// 获取ImportSelector类中需要排除的实例化的类
Predicate
selectorFilter = selector.getExclusionFilter(); if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
// 后置处理类交由后置处理器进行处理,本类涵盖代码的第18行代码处理(this.deferredImportSelectorHandler.process();)
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
// 调用实现ImportSelector的类的selectImports,获取需要实例化类的className
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 从当前ImportSelector需要实例化的类开始向上沿着类继承结构逐层执行将className加入到BeanFactory的beanDefinitionMap中(要排除的类除外),
// 直到遇到的父类是由Java提供的类结束循环
Collection
importSourceClasses = asSourceClasses(importClassNames, exclusionFilter); // 循环处理importClassNames类中再包含的import类
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 类
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
// 将ImportBeanDefinitionRegistrar 类加入到importBeanDefinitionRegistrars集合中
// 会在ConfigurationClassPostProcessor第69行代码进行处理
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());
// 非ImportSelector or ImportBeanDefinitionRegistrar直接处理,放入BeanFactory中
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
......
}
}
通过以上的步骤已将Import中的类注入到BeanFacotry的beanDefinitionMap中等待实例化(ImportBeanDefinitionRegistrar类型的Bean需要通过下面的方式处理才能放入),回到ConfigurationClassPostProcessor的69行代码(this.reader.loadBeanDefinitions(configClasses);),调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions进行处理。
ConfigurationClassBeanDefinitionReader
public void loadBeanDefinitions(Set
configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
......
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 获取所有ImportBeanDefinitionRegistrars进行处理
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
private void loadBeanDefinitionsFromRegistrars(Map
registrars) { registrars.forEach((registrar, metadata) ->
// 调用继承ImportBeanDefinitionRegistrar类中的registerBeanDefinitions将Bean注入到BeanFactory
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}
到这一步Import的所有类已注册到BeanFactory中,那么什么时候对这些类进行初始化呢?回到AnnotationConfigApplicationContext(即AbstractApplicationContext)的refresh方法,通过finishBeanFactoryInitialization(beanFactory)实例化Bean。