ConfigurationClassPostProcessor
ConfigurationClassPostProcessor继承BeanDefinitionRegistryPostProcessor接口,刷新IOC容器时调用postProcessBeanDefinitionRegistry方法实现注解的解析。order=Integer.MAX_VALUE
继承BeanFactoryPostProcessor实现postProcessBeanFactory,完成对配置类的cglib代理和添加一个ImportAwareBeanPostProcessor(1.在实例化完成后配置属性时对配置类添加beanFactory感知;2.在初始化时对实现了ImportAware接口的bean配置importingClass)
具体流程
processConfigBeanDefinitions
- 获得所有BeanNames
- 添加所有配置类到候选集合(full+lite)
- 创建解析器来解析ConfigurationClass
- 解析+验证(Configuration类不为final,@Bean修饰方法可被继承)
- 加载解析的ConfigurationClass
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
// 获得容器中所有beanNames
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
···日志打印beanDef已被定义为ConfigurationClass
}
// 判断是否为配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 无候选直接返回
if (configCandidates.isEmpty()) {
return;
}
// 排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 发现自定义beanName生成器
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
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();
}
// 创建解析器来解析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 {
// 核心1
parser.parse(candidates);
parser.validate();
// 获得所有ConfigurationClass排除已被解析的
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// 创建读取器来处理ConfigurationClass
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 核心2
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
// 如果在加载过程创建了新的bd,确保新的bd被解析
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());
// 将ImportRegistry注册为bean以支持importware
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();
}
}
1. ConfigurationClassParser的parse方法
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 根据不同类型执行不同解析方法
if (bd instanceof AnnotatedBeanDefinition) {
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());
}
}
···异常
}
// 处理需要延迟处理的ImportSelector,在所有配置加载完成后解析
this.deferredImportSelectorHandler.process();
}
// 注解BeanDefinition解析,创建ConfigurationClass
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
1.1 processConfigurationClass
- 判断是否跳过解析 @Conditional是否存在
- 判断当前ConfigurationClass已存在则判断是否有@Import导入,有则合并,否则移除
- 调用doProcessConfigurationClass循环处理直至configClass父类未null或已被处理
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 判断是否跳过解析 @Conditional是否存在
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
// 如果当前ConfigurationClass已存在则判断是否有@Import导入,有则合并,否则移除
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);
}
}
// 调用doProcessConfigurationClass循环处理直至configClass父类未null或已被处理
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
1.2 doProcessConfigurationClass
- 存在@Component注解则判断是否有嵌套的配置类,存在则递归调用processConfigurationClass处理
- 处理@PropertySource,加入environment中,IOC容器的environment必须为ConfigurableEnvironment
- 处理@ComponentScan注解,扫描包位置下的@Component修饰的类(通过includeFilters排除),对生成的bd递归调用prase方法
- 处理@Import注解,分别处理ImportSelector、ImportBeanDefinitionRegistrar及其他配置类,递归processConfigurationClass带入ImportBy处理配置类
- 处理@ImportResource注解,记录到ConfigurationClass的importedResources中
- 处理@Bean注解,记录到ConfigurationClass的beanMethods中
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 递归调用processConfigurationClass处理嵌套配置类
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);
}
···日志
}
// 处理@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) {
// 扫描包位置下的@Component修饰的类(通过includeFilters排除)
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();
}
// 对生成的bd递归调用prase方法
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 分别处理ImportSelector、ImportBeanDefinitionRegistrar及其他配置类
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// 处理@ImportResource注解,记录到ConfigurationClass中
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));
}
// 处理接口上的缺省方法
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);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// 无父类,处理完成
return null;
}
2. loadBeanDefinitions
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
// 遍历加载ConfigurationClass到BeanFactory
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
2.1 loadBeanDefinitionsForConfigurationClass
根据不同ConfigurationClass执行不同的装载方法
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;
}
// 如果是Import则加载为AnnotatedGenericBeanDefinition
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// @Bean方法加载,默认使用方法名作为Bean名,通过设置FactoryBeanName,FactoryMethodName来完成bd的初始化
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// @ImportResource加载,读取资源中的BeanDifinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// ImportBeanDefinitionRegistrar处理,调用registerBeanDefinitions注册BeanDifinition
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
enhanceConfigurationClasses增强配置类
遍历找出所有@Configuration修饰的类,使用cglib动态代理增强配置类对象
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);
MethodMetadata methodMetadata = null;
···省略代码
// 如果当前bean为@Configuration修饰的类加入configBeanDefs中
if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {
···异常日志
configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
}
}
// 为空不增强
if (configBeanDefs.isEmpty()) {
return;
}
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
AbstractBeanDefinition beanDef = entry.getValue();
// If a @Configuration class gets proxied, always proxy the target class
beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
// Set enhanced subclass of the user-specified bean class
Class<?> configClass = beanDef.getBeanClass();
// 代理configClass
Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
// 如果不等表示代理成功,修改bd对应的beanClass
if (configClass != enhancedClass) {
··· 日志
beanDef.setBeanClass(enhancedClass);
}
}
}
enhance增强
- 代理类继承@Configuration修饰的类并且实现EnhancedConfiguration接口感知beanFactory
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
// 已被代理直接返回
if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
···日志
return configClass;
}
Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
···日志
return enhancedClass;
}
private Enhancer newEnhancer(Class<?> configSuperClass, @Nullable ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
// 设置被代理类
enhancer.setSuperclass(configSuperClass);
enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});
enhancer.setUseFactory(false);
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));
// 设置拦截器、过滤器及其类型 默认拦截器:BeanMethodInterceptor BeanFactoryAwareMethodInterceptor NoOp.INSTANCE
enhancer.setCallbackFilter(CALLBACK_FILTER);
enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());
return enhancer;
}
1.1 BeanFactoryAwareMethodInterceptor
当调用setBeanFactory方法时进行拦截
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 找到代理的$$beanFactory字段设置值
Field field = ReflectionUtils.findField(obj.getClass(), BEAN_FACTORY_FIELD);
field.set(obj, args[0]);
// 如果父类实现了BeanFactoryAware则调用其setBeanFactory设置
if (BeanFactoryAware.class.isAssignableFrom(ClassUtils.getUserClass(obj.getClass().getSuperclass()))) {
return proxy.invokeSuper(obj, args);
}
return null;
}
1.2 BeanMethodInterceptor
判断方法含有注解@Bean
public Object intercept(Object enhancedConfigInstance, Method beanMethod, Object[] beanMethodArgs,
MethodProxy cglibMethodProxy) throws Throwable {
ConfigurableBeanFactory beanFactory = getBeanFactory(enhancedConfigInstance);
String beanName = BeanAnnotationHelper.determineBeanNameFor(beanMethod);
// 是否存在@Scope代理
if (BeanAnnotationHelper.isScopedProxy(beanMethod)) {
String scopedBeanName = ScopedProxyCreator.getTargetBeanName(beanName);
if (beanFactory.isCurrentlyInCreation(scopedBeanName)) {
beanName = scopedBeanName;
}
}
// 为了处理bean间方法引用的情况,显式地检查容器中是否有已缓存的实例。
// FactoryBean处理
if (factoryContainsBean(beanFactory, BeanFactory.FACTORY_BEAN_PREFIX + beanName) &&
factoryContainsBean(beanFactory, beanName)) {
Object factoryBean = beanFactory.getBean(BeanFactory.FACTORY_BEAN_PREFIX + beanName);
if (factoryBean instanceof ScopedProxyFactoryBean) {
// Scoped proxy factory beans are a special case and should not be further proxied
}
else {
// 增强
return enhanceFactoryBean(factoryBean, beanMethod.getReturnType(), beanFactory, beanName);
}
}
// 拦截的方法与当前记录的方法一致
if (isCurrentlyInvokedFactoryMethod(beanMethod)) {
···日志
// 调用父类实际方法,创建bean实例
return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs);
}
// 不一致表示@Bean方法内调用了其他方法获得实例,则直接从beanFactory获取
return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName);
}
总结
- 解析时@ComponentScan扫描的组件会直接加入BeanFactory的beanDifinitionMap中,其余需等待读取器加载到beanDifinitionMap中
- deferredImportSelector是在所有配置类解析完成后再处理
- @Bean的加载是通过设置FactoryBeanName,FactoryMethodName来完成
- 解析时通过ConditionEvaluator判断是否需要跳过当前类的解析(@Conditional),加载时通过TrackedConditionEvaluator判断,引入当前类的配置类只要有一个允许解析则通过ConditionEvaluator传入Bean阶段来判断是否需要解析。