项目结构和代码
@Component
public class CustomerBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("CustomerBeanFactoryPostProcessor.postProcessBeanFactory");
}
}
@Component
public class CustomerBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
System.out.println("CustomerBeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry");
AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(NotComponentService.class).getBeanDefinition();
beanDefinitionRegistry.registerBeanDefinition("notComponentService", definition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("CustomerBeanDefinitionRegistryPostProcessor.postProcessBeanFactory");
}
}
@Service
public class HelloService {
}
@Service
public class UserService {
}
public class NotComponentService {
}
@ComponentScan
public class DddApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(DddApplication.class);
}
}
beanFactory 初始化流程
构造器
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
}
this()
首先调用父类构造器创建 beanFactory
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {
private final DefaultListableBeanFactory beanFactory;
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
}
创建 AnnotatedBeanDefinitionReader
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
该方法的逻辑是向 beanFactory 添加五个 postProcessor
此时无参构造已经执行完成,该构造一共做了三件事情
- 调用父类 GenericApplicationContext 的无参构造,创建 DefaultListableBeanFactory
- 创建 AnnotatedBeanDefinitionReader,添加五个 postProcessor的beanDefinition 到 beanFactory
- 创建 ClassPathBeanDefinitionScanner
register()
register(componentClasses) 的作用就是调用 AnnotatedBeanDefinitionReader.register() 将启动类注册到 beanDefinition
beanFactory refresh()
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
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");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
prepareBeanFactory()
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
向 beanFactory 添加了两个 beanPostProcessor
添加四个组件
添加默认的 enviroment 组件
invokeBeanFactoryPostProcessors()
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
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.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
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.
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.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
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);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
ConfigurationClassPostProcessor
ConfigurationClassPostProcessor是一个BeanFactoryPostProcessor,用于处理一些配置信息和注解扫描,并且该处理器执行的时候有优先级顺序,优先执行PriorityOrdered,然后执行Ordered,最后执行默认没有优先级的处理器。
并且ConfigurationClassPostProcessor 是 spring框架中最重要的BeanFactoryPostProcessor,也是最重要的内置组件之一
作用:
- 对于候选配置类使用CGLIB Enhancer增强
- 解析处理@PropertySource 注解
- 解析@ComponentScan注解,扫描@Configuration、@Service、@Controller、@Repository和@Component注解并注册BeanDefinition
- 解析@Import注解,然后进行实例化,并执行ImportBeanDefinitionRegistrar的registerBeanDefinitions逻辑,或者ImportSelector的selectImports逻辑
- 解析@ImportResource注解,并加载相关配置信息
- 解析方法级别@Bean注解并将返回值注册成BeanDefinition
- 注册ImportRegistry到容器中,用于处理ImportAware
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// 候选配置类定义列表
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获取容器中所有bean定义的名字
String[] candidateNames = registry.getBeanDefinitionNames();
// 循环名字
for (String beanName : candidateNames) {
// 获取bean定义
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
// 省略...
}
// 查看bean是否是ConfigurationClass
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
// 加入到候选配置类定义列表
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 没有@Configuration的bean就返回
if (configCandidates.isEmpty()) {
return;
}
// 省略排序,beanName生成规则,环境变量等...
// 构造一个配置类解析器,用来把bean定义的重要信息提取转化为ConfigurationClass
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 {
// 核心解析流程,重要!
// 其实就是把类上面的特殊注解解析出来,最终封装成 BeanDefinition 注册到工厂
parser.parse(candidates);
parser.validate();
// 获取解析器中解析出的配置类ConfigurationClass:parser.getConfigurationClasses()
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 过滤掉已解析的配置类
configClasses.removeAll(alreadyParsed);
// 构造一个bean定义读取器
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 读取ConfigurationClass获取衍生bean定义并注册到容器
// 这里是去真正的注册!刚刚在解析 @Import、@Bean、@Import 等注解的时候,
// 并没实际创建 BeanDefinition 并注册,而是将数据暂存起来
this.reader.loadBeanDefinitions(configClasses);
// 加入已解析配置类
alreadyParsed.addAll(configClasses);
// 清空候选配置类定义列表
candidates.clear();
// 如果容器中bean定义有新增
// 这样做主要是防止有些 Bean 没有注册
if (registry.getBeanDefinitionCount() > candidateNames.length) {
/** 查找出新增的配置类bean定义 start **/
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));
}
}
}
/**查找出新增的配置类bean定义 end , 最终新的配置bean定义加入到候选配置类定义列表 **/
// 覆盖所有beanName,为下一次判断是否有新增
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty()); // 只要候候选配置类定义列表不为空就一直循环下去
// 省略...
}
上面的代码比较长,但流程很清晰,总结一下
- 查找spring容器中的配置类bean定义,存储
候选列表
- 使用解析器,解析
候选列表
中的配置类bean定义,根据配置的扫描范围把相关的类都解析为ConfigurationClass对象(其中@CommpentScan下扫描的类直接注册bean定义) - 使用读取器,读取上一步解析出的新未解析ConfigurationClass,注册相关bean定义
- 清空
候选列表
- 继续查询spring容器,如果有新增的配置类bean定义,读取加入
候选列表
,跳转回第2步
上文ConfigurationClassPostProcessor对parser具体使用主要有三处
- 初始化构造parser,传入了BeanDefinitionRegistry等构造传参数
- 调用parse方法解析bean定义集合
- 通过getConfigurationClasses方法获取解析结果configurationClasses
ConfigurationClassParser中一个属性configurationClasses,用来存放解析出来的结果
class ConfigurationClassParser {
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();
}
解析(parse)的重点责任就是根据传入的参数(bean定义列表)转化为Map<ConfigurationClass, ConfigurationClass>,下面重点分析分析方法:parse
方法:
Parser#parse()
org.springframework.context.annotation.ConfigurationClassParser#parse()
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 循环
for (BeanDefinitionHolder holder : configCandidates) {
// 获取bean定义
BeanDefinition bd = holder.getBeanDefinition();
try {
// 根据bean定义的类型走不通参数的重载parse方法
// 扫描注解得到的 BeanDefinition
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
// 非扫描注解得到的 BeanDefinition
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
// 省略catch...
}
// 处理延迟加载的 importSelect?为什么要延迟加载,估计就是为了延迟吧
this.deferredImportSelectorHandler.process();
}
org.springframework.context.annotation.ConfigurationClassParser#processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass) {
// 根据注解信息判断是不是跳过解析
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 处理 Imported 的情况,就是当前这个注解类有没有被别的类 import
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
return;
} else {
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 递归地处理配置类及其超类层次结构
SourceClass sourceClass = asSourceClass(configClass);
do {
// 处理配置类
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
又是一个循环,调用doProcessConfigurationClass
方法,如果有返回值,递归调用doProcessConfigurationClass,看spring的注释说递归解析配置类和他的父类,所以这代码的意思就是解析配置类,如果有父类再解析父类,如果父类有父类再一直解析下去。
最后this.configurationClasses.put(configClass, configClass);
就是把上一步根据bean定义生成的ConfigurationClass对象存入解析的结果map:configurationClasses,实际上,对解析结果的添加只有这一处代码
如果单单看到这里,parser的功能就是把传入的多个bean定义循环转换为ConfigurationClass并存入解析结果中,相当于传入多少bean定义就转换多少ConfigurationClass对象
单parse方法的功能远不止如此,重点在doProcessConfigurationClass
方法
doProcessConfigurationClass
org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
// 1.内部类 这一步看看有没有内部类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
processMemberClasses(configClass, sourceClass, filter);
}
// 2.@PropertySource 这一步解析@PropertySource注解,更改配置文件位置时会使用,一般使用默认位置,不咋更改
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
// 省略...
}
// 3.@ComponentScan 这一步就很重要了,解析@ComponentScan注解
// 此处或扫描到 @ComponentScan 注解包下面的所有加了 @Component、@Service 等注解的类
// 注意的是,每扫描到一个符合条件的类,都要进行递归扫描,重新调用 doProcessConfigurationClass() 方法
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) {
// 这里扫描出来所有 @Component,并且把扫描的出来的普通 bean 放到 bdMap 当中
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查扫描的定义集是否有任何进一步的配置类,并在需要时进行递归解析
// 检查扫描出来的类当中是否还有 configuration
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
// 获取bean定义
bdCand = holder.getBeanDefinition();
}
//判断是不是配置类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 检查扫描出来的配置类有没有配置类,进行再次解析,递归调用
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 4.@Import 解析@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 5.@ImportResource解析@ImportResource解析
// 这里只是去解析配置文件的位置添加到配置类的 importedResources 中,没有进行扫描处理
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);
}
}
// 6.@Bean 解析带有@Bean注解的方法,加入到configClass的beanMethods属性中
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 6.接口@Bean 解析实现的接口中带有@Bean注解的默认方法,加入到configClass的beanMethods属性中
processInterfaces(configClass, sourceClass);
// 7.父类 如果有父类返回父类,以继续解析
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();
}
}
// 没有父类,解析结束
return null;
}
这个方法很长,主要包含以下几个功能
- 解析内部类
- 解析@PropertySource注解
- 解析@ComponentScan注解,扫描指定包下的所有@Component类,直接注册bean定义至spring,并递归解析
- 解析@Import注解
- 解析@ImportResource注解
- 解析@Bean
- 解析实现接口中的@Bean
- 返回父类
所以doProcessConfigurationClass这一步的重点工作就是扫描某个配置类的注解,根据注解功能找到指定扫描范围的类,递归
解析(调用parse或processConfigurationClass方法)
比如@ComponentScan就是扫描到basePackages指定路径下的类,然后通过递归调用parse解析这些类,@Import通过value属性指定的类,递归调用processConfigurationClass解析
重点这个递归
,有了它就可以实现一个bean定义解析出多个ConfigurationClass对象
这里有个特例,@ComponentScan扫描的类会被直接注册到spring容器
解析内部类
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
也就是说如果一个类有@Component注解,processMemberClasses内部会解析当前类的内部类,如果是配置类,则会递归
调用processConfigurationClass去解析这个内部类
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) {
// 如果是配置类,加入候选
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();
}
}
}
}
}
解析@ComponentScan
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
componentScanParser
内部有个scaner(扫描器),扫描@Component
注解的类,包括子注解@Configuration
,@Service
等(这过程还会直接把扫描到的类注册bean定义)
org.springframework.context.annotation.ComponentScanAnnotationParser#parse
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// Spring 自己 new 的一个 ClassPathBeanDefinitionScanner 进行扫描!这个类见到很多次了
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);
// 设置扫描器的 BeanName 生成器
scanner.setBeanNameGenerator(useInheritedGenerator ?
this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass));
// 设置 componentScan 的代理模式
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"));
// 看看 componentScan 注解是否设置了 includeFilters 属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
// 看看 componentScan 注解是否设置了 excludeFilters 属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
// 看看 componentScan 注解是否设置了 lazyInit 属性
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
// 此集合放的是扫描的路径
Set<String> basePackages = new LinkedHashSet<>();
// 获取componentScan注解的basePackages属性
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));
}
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
// 存储创建出的 BeanDefinitionHolder
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 依次扫描每个包中的相关注解,创建获取到所有的 BeanDefinition
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// 生成 Bean 的名称
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
// 包装成 BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 创建代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册到上下文工厂
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
扫描的核心是 findCandidateComponents 方法,这个方法就是寻找到 @Component 和 @Component 的衍生注解的类。
org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents
回到 org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
循环判断扫描到的类是否是ConfigurationClass,如果是则递归
解析
解析@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
参数getImports
方法获取到了当前配置类所有@Import注解指定的类集合,然后进入processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
// 省略...
// 循环所有@Import指定的类
for (SourceClass candidate : importCandidates) {
// 如果这个类实现了ImportSelector,即导入多个类
if (candidate.isAssignable(ImportSelector.class)) {
// 实例化这个导入的ImportSelector类
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
// 省略一些过滤...
// 如果是延迟导入,交给deferredImportSelectorHandler处理
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);
}
}
// 如果这个类实现了ImportBeanDefinitionRegistrar
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// 实例化这个ImportBeanDefinitionRegistrar类
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
// 加入该类到当前配置类解析对象ConfigurationClass的importBeanDefinitionRegistrars列表属性中
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// 排除上面两种情况,这个类就是个普通类
else {
// 省略...
// 递归解析这个类
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
}
这里涉及的内容较多,主要分几种情况
- 如果导入的就是普通类 直接
递归
解析这个类 - 如果导入的类实现了ImportBeanDefinitionRegistrar(导入的bean定义注册器) 直接实例化这个类,并加入到当前解析配置类的importBeanDefinitionRegistrars(列表)属性中,以便后续调用其
registerBeanDefinitions
方法 - 如果导入的是实现了ImportSelector的普通类(多类导入) 直接实例化这个类,循环
selectImports
方法放回的多个类,递归调用processImports - 如果导入的是实现了DeferredImportSelector的特殊ImportSelector类(延迟多类导入) 直接实例化这个类,委托给解析器内部的deferredImportSelectorHandler处理,deferredImportSelectorHandler内部把这个实例对象和当前解析类封装为DeferredImportSelectorHolder, 暂存入解析器内部的deferredImportSelectors属性 因为是延迟,所以这里暂存了一下,并没有像普通ImportSelector那样循环递归解析processImports,而其真正的执行实际就是上文parse主方法最后的那一句
this.deferredImportSelectorHandler.process()
,而process方法内部依然是循环递归processImports方法,只不过延迟了,相当于所有的类被解析过才开始解析DeferredImportSelector导入的类
解析@Bean
// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
这里通过解析当前配置类@Bean方法,并将方法打包为BeanMethod存入配置类beanMethods属性中
总结Parser
基本上parser内部解析的重点方法都分析完了,总结一下,parser都干了什么?
-
parser作为一个解析器,根据传入的配置类解析出多个
ConfigurationClass
对象 -
配置类实际上是一个树形结构,他的子节点包含@ComponentScan扫描到的配置类,@Import引入的普通类等
-
而spring中这个树结构的根节点一般就是用户定义的主启动类
-
parser通过递归解析完成整个树的解析(解析成多个ConfigurationClass对象),并把解析结果存入parser内部
configurationClasses
属性 -
parser解析某个配置类节点过程中 会把其@Bean方法加入ConfigurationClass对象的属性
beanMethods
列表中 会把@Import注解引入的ImportBeanDefinitionRegistrar加入ConfigurationClass对象的属性importBeanDefinitionRegistrars
列表中 会把@Import注解引入的DeferredImportSelector加入到解析器内部的属性deferredImportSelectors
列表中,延迟到所有节点解析完成后再统一解析 -
在解析某配置类的@ComponentScan注解时,扫描到的类会同时注册bean定义至spring容器
所以最终结果是把根配置类下的整个树扫描,生成多个ConfigurationClass
对象,同时@ComponentScan扫描到的配置类会直接注册bean定义
最后画个图梳理整个解析过程
DeferredImportSelector只不过是延迟导入,从整个解析过程来看最终结果与@Import一样
Reader
相比于parser,reader的任务轻松多了,主要任务就是把parser解析出的ConfigurationClass
集合读取并转换为bean定义,并最终注册到spring容器
回到 org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
// 省略的
// 注册被Import引入的类,标识ConfigurationClass.isImported==true
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 注册@Bean的工厂方法,存储在ConfigurationClass.beanMethods属性中
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// ImportedResource(忽略)
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 执行ImportBeanDefinitionRegistrar实现注册用户自定义bean定义,存储在ConfigurationClass.importBeanDefinitionRegistrars属性中
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
Parser注册了@ComponentScan
扫描的bean定义,而Reader主要注册了这几个bean定义
- 通过@Import引入的(标识ConfigurationClass.isImported==true)
- @Bean的工厂方法(存储在ConfigurationClass.beanMethods属性中)
- 执行ImportBeanDefinitionRegistrar实现注册用户自定义bean定义(存储在ConfigurationClass.importBeanDefinitionRegistrars属性中)
这么一看Reader反而成了捡漏的了...,就是把Parser没注册的bean定义都注册上
其中loadBeanDefinitionsFromRegistrars这步就是执行ImportBeanDefinitionRegistrar实现的registerBeanDefinitions
方法,即用户自定义注册bean常用的@Import+ImportBeanDefinitionRegistrar模式的实际执行时机
回到 org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
可以看到我没自定义的 bean已经注册进容器了
Ordered BeanDefinitionRegistryPostProcessors
all other BeanDefinitionRegistryPostProcessors
执行自定义的 BeanDefinitionRegistryPostProcessor,并向容器中注册一个 beanDefition
beanDefinitionRegisterPostProcesso.rpostProcessBeanFactory
接下来按照优先级依次执行 BeanFactoryPostProcessor