上篇传送门
上篇介绍了component-scan标签的解析,把扫描到的@Component类文件扫描到,然后生成bean定义信息并注册到工厂,工厂注册完后,又注册了注解解析内部定义信息(后置处理器)以及监听器,接下来咱们继续看下是如何执行后置处理器的
了解ConfigurationClassPostProcessor之前,先看下关系图,实现了BDRPP、BFPP、PriorityOrdered接口,看到这里都会想到是在哪里进行处理了
咱们上篇了解到spring只是注册了bean的定义信息,对于internal*对应的类并没有进行实例化,那执行BFPP的时候就必须先创建出bean对象(后面咱们会详细聊,这里先不展开),然后进行调用
- 注解什么时候解析的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 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 candidates = new linkedHashSet<>(configCandidates);
//用于存储已经解析过的对象
Set alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 解析带有@Controller、@import、@importResource、@ComponentScan、@ComponentScans、@Bean的Bean定义信息
parser.parse(candidates);
parser.validate();
// 存储解析的bean定义信息
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定义信息到工厂,方便实例化
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 如果新注册了bean定义信息
if (registry.getBeanDefinitionCount() > candidateNames.length) {
// 获取解析加载后的bean定义信息
String[] newCandidateNames = registry.getBeanDefinitionNames();
// 加载之前的bean定义信息
Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
// 已经解析过的
Set 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 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,PredicateConfigurationClassParser.doProcessConfigurationClassfilter) 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); }
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, PredicateConfigurationClassParser.processMemberClasses 解析@Componentfilter)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 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 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 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; }
@Component
public class CommonConfig {
@Component
class InnerClass{
@Component
class InnerInnerClass{
}
}
}
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,PredicateConfigurationClassParser.processPropertySource 解析@PropertySource并把配置文件加载到propertySourceListfilter) throws IOException { // 获取@Component内部配置类 Collection memberClasses = sourceClass.getMemberClasses(); if (!memberClasses.isEmpty()) { List 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(); } } } } }
@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 SetConfigurationClassParser.getimports 递归获取@import注解标注的类getimports(SourceClass sourceClass) throws IOException { // 存放加载的资源类 Set imports = new linkedHashSet<>(); // 递归标识 Set visited = new linkedHashSet<>(); // 处理@import注解导入的类 collectimports(sourceClass, imports, visited); return imports; }
private void collectimports(SourceClass sourceClass, SetConfigurationClassParser.processimports 解析@imports, Set 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")); } }
private void processimports(ConfigurationClass configClass, SourceClass currentSourceClass,CollectionimportCandidates, Predicate 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 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 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(); } } }



