此篇介绍内容如下
BeanDefinitionMap 的填充中 BeanFactoryPostProcessor(ConfigurationClassPostProcessor)做了什么
- 1.子类的扫描解析注解(递归思想循环解析)
- 2.父类的cglib代理
我们先来看看环境图
在进入解析之前会介绍一下这三个类ConfigurationClassUtils,ConfigurationClass,ConfigurationClassParser
我们直接看调用链里面写了一些自己的见解
- org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors
- org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.BeanFactoryPostProcessor>)
- org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
- org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); String[] candidateNames = registry.getBeanDefinitionNames(); // 除去系统内置的就只有 AppConfig.class for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found if (configCandidates.isEmpty()) { return; } // Sort by previously determined @Order value, if applicable 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; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } // Parse each @Configuration class 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 { //解析AppConfig.class 配置类 parser.parse(candidates); parser.validate(); // 获取解析到的 @Component 的类 和 @Configuration 的类 // 当前环境主要有三个(AppConfig.class,PersonBo.class,TestBo.class,null,null,null)自定义注解有import注解的beanName为空 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的所有方法 // 并将方法返回的对象封装为一个BeanDefinition 注册到 BeanDefinitionMap<beanMethodName,BeanDefinition> this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); 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()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes // 将ImportRegistry注册为bean,以支持支持ImportAware @Configuration类 放到单例池中(一级缓存) 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(); } }
parser.parse(candidates);
// 开始解析 AppConfig.class public void parse(Set<BeanDefinitionHolder> configCandidates) { for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { // @Configuration 注解的类都是 AnnotatedBeanDefinition 类型的bd if (bd instanceof AnnotatedBeanDefinition) { // 将获取到的 注解 及 beanName 开始解析 parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } //有删减 } this.deferredImportSelectorHandler.process(); }
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { // 重新构建 ConfigurationClass 对象封装 beanName 和 所有注解 processConfigurationClass(new ConfigurationClass(metadata, beanName)); }
protected void processConfigurationClass(ConfigurationClass configClass) 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); do { sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); this.configurationClasses.put(configClass, configClass); }
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 解析是否包含 @Component(一部分注解直接继承了@Component) 注解 if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // Recursively process any member (nested) classes first // 首先递归地处理任何成员(嵌套的)类 processMemberClasses(configClass, sourceClass); } // 解析包含是否 @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(); } } // 解析包含是否 @ComponentScans 注解 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:ScannedGenericBeanDefinition 类型的 BeanDefinition 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(); } // 循环解析该 BeanDefinition 里面的所有的 @Bean 注解的方法 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { // 继续调用重载的 parse方法解析 递归的思想 最后将@Bean 注解的所有方法 放到Set<BeanMethod>集合中 parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // 解析包含是否 @Import 注解,和实现了importselector接口 ImportBeanDefinitionRegistrars // 并通过 @Import 进行 导入 后存放到ConfigurationClass类属性中等待二次解析 processImports(configClass, sourceClass, getImports(sourceClass), 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); } } // 解析并获取AppConfig.class 中 @Bean注解的所有方法 放到Set<BeanMethod>集合中 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces processInterfaces(configClass, sourceClass); // Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; }
第一个注意点processMemberClasses(configClass, sourceClass);会递归的思想返回以前的方法再次执行解析过程
ConfigurationClassParser#doProcessConfigurationClass#processMemberClasses
ConfigurationClassParser#processMemberClasses#processConfigurationClass
ConfigurationClassParser#processConfigurationClass
ConfigurationClassParser#doProcessConfigurationClass
ConfigurationClassParser#doProcessConfigurationClass#processMemberClasses每个类的@Bean 方法都被放到了这里
ConfigurationClass ---> configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
ConfigurationClassParser#parse()执行完后会得到所有的configClasses(BeanMethod在里面),用来解析@Bean注解的
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
在继续上面的代码ConfigurationClassParser#this.reader.loadBeanDefinitions(configClasses);
这一个方法完成了@Bean注解的方法解析 和封装了一个 BeanDefinition 并且注册到了BeanDefinitionMap中
//解析类 public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); for (ConfigurationClass configClass : configurationModel) { // 分别解析这三个类(beanName不为空的) loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }
// 再来loadBeanDefinitionsForBeanMethod(beanMethod);解析方法
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 注册 包含@Import 的类 if (configClass.isImported()) { registerBeanDefinitionForImportedConfigurationClass(configClass); } //@Bean 循环获取三个类中有 @Bean 注解的方法 for (BeanMethod beanMethod : configClass.getBeanMethods()) { // 开始处理,封装为一个 BeanDefinition 来注册 loadBeanDefinitionsForBeanMethod(beanMethod); } //@ImportedResources 注册 loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); //实现 ImportBeanDefinitionRegistrars 接口的注册 loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
loadBeanDefinitionsForBeanMethod(beanMethod);完成属性的封装及注册
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { ConfigurationClass configClass = beanMethod.getConfigurationClass(); MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); // Do we need to mark the bean as skipped by its condition? if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; } if (configClass.skippedBeanMethods.contains(methodName)) { return; } AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); Assert.state(bean != null, "No @Bean annotation attributes"); // Consider name and any aliases List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name"))); String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden for (String alias : names) { this.registry.registerAlias(beanName, alias); } // Has this effectively been overridden before (e.g. via XML)? if (isOverriddenByExistingDefinition(beanMethod, beanName)) { if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) { throw new BeanDefinitionStoreException(); } return; } ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) {// 处理@Bean 注解并有 static 修饰的方法 // static @Bean method beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(methodName); } else { // instance @Bean method 处理@Bean 注解的方法 beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(methodName); } // 开始封装 BeanDefinition 的其它属性 beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor. SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); Autowire autowire = bean.getEnum("autowire"); if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); } boolean autowireCandidate = bean.getBoolean("autowireCandidate"); if (!autowireCandidate) { beanDef.setAutowireCandidate(false); } String initMethodName = bean.getString("initMethod"); if (StringUtils.hasText(initMethodName)) { beanDef.setInitMethodName(initMethodName); } String destroyMethodName = bean.getString("destroyMethod"); beanDef.setDestroyMethodName(destroyMethodName); // Consider scoping ScopedProxyMode proxyMode = ScopedProxyMode.NO; AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (attributes != null) { beanDef.setScope(attributes.getString("value")); proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } // Replace the original bean definition with the target one, if necessary BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) { BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); } if (logger.isTraceEnabled()) { logger.trace(); } // 将封装完整的 BeanDefinition 注册到 BeanDefinitionMap 中 this.registry.registerBeanDefinition(beanName, beanDefToRegister); }
BeanDefinitionMap.put已经填充完,而ioc容器的初始化还并未完成,还需填充singletonObjectsMap(通俗点理解成单例池或者一级缓存)
涉及到了bean的生命周期我们后面再来继续探讨。先看第二点
第二点实现父类方法并进行CGLIB代理
我们回到这个方法中进去
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()#invokeBeanFactoryPostProcessors()
ConfigurationClassPostProcessor#postProcessBeanFactory()
@Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { int factoryId = System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { throw new IllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. // 1.该方法子类已经执行过,通过集合过滤后显然实现 BeanDefinitionRegistryPostProcessor 的接口不会执行 // 2.还是回到了 AppConfig.class 这个配置类 已经解析过 通过验证后会直接返回 processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } //给 AppConfig.class 配置类做cglib代理。 enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); }
先注意最后一行,是我以后要做笔记的博客,添加一个bean的后置处理器(注意不是beanFactory的后置处理器)
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
beanFactory的后置处理器执行完成后会开始bean的后置处理器。
可以看看这篇博客
spring bean的后置处理器-BeanPostProcessor
我们继续看这儿enhanceConfigurationClasses(beanFactory);
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { // 获取到 beanName = AppConfig.class 的 BeanDefinition BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {//此时为true 因为之前的解析已经赋值了 if (!(beanDef instanceof AbstractBeanDefinition)) { throw new BeanDefinitionStoreException(); } else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { logger.info(); } // 存入map中 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; } //开始 CGLIB 增强 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); try { // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader); if (configClass != null) { // 此处的判断为 是否已经代理过了,代理过的类会设置一个属性 // 如果已经代理则返回当前对象,如果没有则进行CGLIB代理 返回代理对象 Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isTraceEnabled()) { logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } beanDef.setBeanClass(enhancedClass); } } } catch (Throwable ex) { throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex); } } }
如何判断一个配置类是否已经被CGLIB增强过呢
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) { //判断是否已经被cglib代理过了 if (EnhancedConfiguration.class.isAssignableFrom(configClass)) { if (logger.isDebugEnabled()) { logger.debug(); } // Proxy.newProxyInstance(this.getClass().getClassLoader(), this.getClass().getInterfaces(), new InvocationHandler() { // @Override // public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // Object invoke = method.invoke(proxy, args); // return invoke; // } // }); return configClass; } Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader)); if (logger.isTraceEnabled()) { logger.trace(); } return enhancedClass; }
因为进行CGLIB增强的配置类设置了一个属性,再根据属性来判断
/** * Creates a new CGLIB {@link Enhancer} instance. */ 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)); enhancer.setCallbackFilter(CALLBACK_FILTER); enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes()); return enhancer; }
本篇博客以介绍完成。当前容器中大概模型为(橙色的线部分注解及接口导入类主要经过ConfigurationClassPostProcessor而二次扫描解析)
refresh()#registerBeanPostProcessors(beanFactory);
这行代码添加系统内置的和自定义的bean处理器完成后下面可以先了解下这张图
下篇我们开始窥探 spring bean漫长的一生经历了什么