上篇传送门
上篇介绍了component-scan标签的解析,把扫描到的@Component类文件扫描到,然后生成bean定义信息并注册到工厂,工厂注册完后,又注册了注解解析内部定义信息(后置处理器)以及监听器,接下来咱们继续看下是如何执行后置处理器的
了解ConfigurationClassPostProcessor之前,先看下关系图,实现了BDRPP、BFPP、PriorityOrdered接口,看到这里都会想到是在哪里进行处理了
咱们上篇了解到spring只是注册了bean的定义信息,对于internal*对应的类并没有进行实例化,那执行BFPP的时候就必须先创建出bean对象(后面咱们会详细聊,这里先不展开),然后进行调用
文章知识点
- 注解什么时候解析的
- BDRPP处理了哪些注解
- 注解标注的类实例化了吗
PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors 执行BDRPP
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//执行对应的接口方法
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 执行模板方法
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//记录符合条件的bean定义信息包装类
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取所有的bean定义信息
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
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);
}
// 检查是否符合条件
// 规则:@Component、@ComponentScan、@Import、@ImportResource、@Bean修饰的bean定义
}else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 如果没有符合条件的,直接返回了,说明这个项目比较老,基本是依靠xml方式配置的
if (configCandidates.isEmpty()) {
return;
}
// checkConfigurationClassCandidate方法进行判断的时候最后进行order值获取,并赋值了,这里进行排序
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
SingletonBeanRegistry sbr = null;
// 这里的registry默认是DefaultListableBeanFactory
// 不了解类关系的 可以查下前面文章,spring大体了解 https://blog.csdn.net/xiaomengxin521/article/details/123277648
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
// 如果不存在自定义bean名称生成器
if (!this.localBeanNameGeneratorSet) {
// 尝试获取并设置
BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
//保证环境信息(后面会对咱们的占位符进行赋值)
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 创建一个解析对象
ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 定义一个容器,用于存放解析出来的bean定义信息
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//用于存储已经解析过的对象
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的Bean定义信息
parser.parse(candidates);
parser.validate();
// 存储解析的bean定义信息
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());
}
// 注册bean定义信息到工厂,方便实例化
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 如果新注册了bean定义信息
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 获取解析加载后的bean定义信息
String[] newCandidateNames = registry.getBeanDefinitionNames();
// 加载之前的bean定义信息
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());
// 注册通知
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
ConfigurationClassUtils.checkConfigurationClassCandidate
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
// 获取全限定类名
String className = beanDef.getBeanClassName();
// 猜测是判断是正常流程的bean定义信息,像FactoryBean不进行解析
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
// 获取到注解信息
AnnotationMetadata metadata;
// 如果属于注解标注的bean定义信息
if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// 排除掉不能加载bean定义信息
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
metadata = AnnotationMetadata.introspect(beanClass);
}
else {
try {
//强制去获去注解metadata
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);
}
// 如果强制拿不到直接返回false
return false;
}
}
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// 如果是Configuration注解修饰,并且是动态代理的,标识为 full
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// isConfigurationCandidate 判断是否是@Component、@ComponentScan、@Import、@ImportResource、@Bean注解修饰
// 如果被@Configuration注解修改了,那么里面是可以配置@Bean,所以最后需要判断下
// 如果是这些注解修饰的bean定义信息都会被标识为普通的对象 标识为 lite
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}else {
return false;
}
// 到这里已经确定是注解修饰的bean,并且是被spring认可的正常流程创建的bean
//获取order值赋给bean定义信息
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order);
}
return true;
}
ConfigurationClassParser.processConfigurationClass
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);
}
return;
}
else {
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 获取到类信息
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 开始执行配置类的解析
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 添加到缓存
this.configurationClasses.put(configClass, configClass);
}
ConfigurationClassParser.doProcessConfigurationClass
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)throws IOException {
// 如果是@Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 需要递归进行解析内部的配置类
processMemberClasses(configClass, sourceClass, filter);
}
// 解析 @PropertySource
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");
}
}
// 处理@ComponentScan注解
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) {
// 扫描路径的对应的注解,并生成bean定义信息
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 验证是否有符合条件(上面有讲解)
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 对扫描到的配置进行递归解析
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 处理@ImportResource
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);
}
}
// 处理 @Bean
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理接口中的注解,1.8之后支持
processInterfaces(configClass, sourceClass);
// 处理父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// 返回父类,然后继续解析父类
return sourceClass.getSuperClass();
}
}
return null;
}
ConfigurationClassParser.processMemberClasses 解析@Component
@Component
public class CommonConfig {
@Component
class InnerClass{
@Component
class InnerInnerClass{
}
}
}
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,Predicate<String> filter) throws IOException {
// 获取@Component内部配置类
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);
}
}
// 配置的注解类是可以添加@Order注解的,这里对Order进行排序
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();
}
}
}
}
}
ConfigurationClassParser.processPropertySource 解析@PropertySource并把配置文件加载到propertySourceList
@Configuration // 这里必须要添加
@PropertySource(value = "application.properties")
public class CommonConfig {
}
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
// 获取@PropertySource 属性值
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
// 获取value值 value=“classpath*:*.properties”
String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
//得到资源工厂
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
for (String location : locations) {
try {
// 处理占位符
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
Resource resource = this.resourceLoader.getResource(resolvedLocation);
// 解析配置文件,把解析出的配置文件加载到 propertySourceList
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex) {
if (ignoreResourceNotFound) {
if (logger.isInfoEnabled()) {
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
}
}else {
throw ex;
}
}
}
}
ConfigurationClassParser.getImports 获取到@Import所加载的资源
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
// 存放加载的资源类
Set<SourceClass> imports = new LinkedHashSet<>();
// 递归标识
Set<SourceClass> visited = new LinkedHashSet<>();
// 处理@Import注解导入的类
collectImports(sourceClass, imports, visited);
return imports;
}
ConfigurationClassParser.getImports 递归获取@Import注解标注的类
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)throws IOException {
if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName();
if (!annName.equals(Import.class.getName())) {
// 如果存在多层嵌套关系,那么进行递归获取
collectImports(annotation, imports, visited);
}
}
// 把@Import 标注的类添加到集合中
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
}
}
ConfigurationClassParser.processImports 解析@
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 {
// 循环前面扫描到的所有@Import标注的类
for (SourceClass candidate : importCandidates) {
// 如果属于ImportSelector ,
if (candidate.isAssignable(ImportSelector.class)) {
// 创建实例
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 {
//不需要延期处理,那么进行递归处理(@Import类下有可能还有@Import)
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// 处理 ImportBeanDefinitionRegistrar类型
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar = ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}else {
// 当作配置类进行处理 @Configuration
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();
}
}
}