序言
前两篇文章介绍了invokeBeanFactoryPostProcessors的执行流程,和自定义实现BeanDefinitionRegistryPostProcessor类的方式方法。
这篇文章会主要介绍Spring启动加载xml时,ConfigurationClassPostProcessor类是如何加载到Spring中,并且看看这个类中都做了些什么。
ConfigurationClassPostProcessor这个类在Spring中非常重要,并且之后在SpringBoot中也有涉及。
component-scan
介绍ConfigurationClassPostProcessor之前就不得不说一下context component-scan标签是如何进行加载解析的。
<context:component-scan base-package="com.xxx" ></context:component-scan>
我们在Spring中通常都用 < context:component-scan >标签来实现包的扫描,而xml在加载解析时。
如果碰到默认的 bean、beans、import、alias标签,会走一套解析流程。
除此之外,其余每个标签中的每个属性都会有单独的Parser类来进行单独的解析。
component-scan解析流程图
源码
通过源码来仔细看上面的每一步都做了什么。
custom标签解析流程之前帖子中都有提过,不熟悉的这篇帖子中都有介绍。
spring.handlers
加载handlers文件并转换成Map,通过key找到context对应的handler
ContextNamespaceHandler
执行Handler下init()方法进行初始化,创建context标签下每一个属性的Parser,解析时通过key value形式获取到具体的Parser
public class ContextNamespaceHandler extends NamespaceHandlerSupport {@Overridepublic void init() {registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());}
}
parseCustomElement
通过key获取到具体的Handler
@Nullablepublic BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {// 获取对应的命名空间String namespaceUri = getNamespaceURI(ele);if (namespaceUri == null) {return null;}// 根据命名空间找到对应的NamespaceHandlerspringNamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);if (handler == null) {error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);return null;}// 调用自定义的NamespaceHandler进行解析return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}
parse
handler调用具体的parse()方法进行元素解析。
@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {// 获取元素的解析器BeanDefinitionParser parser = findParserForElement(element, parserContext);return (parser != null ? parser.parse(element, parserContext) : null);}
ComponentScanBeanDefinitionParser
解析context标签的 component-scan元素,所以找到具体ComponentScanBeanDefinitionParser类parse方法。
public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {@Override@Nullablepublic BeanDefinition parse(Element element, ParserContext parserContext) {// 获取<context:component-scan>节点的base-package属性值String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);// 解析占位符basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);// 解析base-package(允许通过,;\t\n中的任一符号填写多个)String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);// Actually scan for bean definitions and register them.// 构建和配置ClassPathBeanDefinitionScannerClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);// 使用scanner在执行的basePackages包中执行扫描,返回已注册的bean定义Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);// 组件注册(包括注册一些内部的注解后置处理器,触发注册事件)registerComponents(parserContext.getReaderContext(), beanDefinitions, element);return null;}
}
doScan
获取base-package属性所对应的包名, 并加载所有能够被识别的Bean,封装到BeanDefinition中并注册。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();// 遍历basePackagesfor (String basePackage : basePackages) {// 扫描basePackage,将符合要求的bean定义全部找出来Set<BeanDefinition> candidates = findCandidateComponents(basePackage);// 遍历所有候选的bean定义for (BeanDefinition candidate : candidates) {// 解析@Scope注解,包括scopeName和proxyModeScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(scopeMetadata.getScopeName());// 使用beanName生成器来生成beanNameString beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);if (candidate instanceof AbstractBeanDefinition) {// 处理beanDefinition对象,例如,此bean是否可以自动装配到其他bean中postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);}if (candidate instanceof AnnotatedBeanDefinition) {// 处理定义在目标类上的通用注解,包括@Lazy,@Primary,@DependsOn,@Role,@DescriptionAnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);}// 检查beanName是否已经注册过,如果注册过,检查是否兼容if (checkCandidate(beanName, candidate)) {// 将当前遍历bean的bean定义和beanName封装成BeanDefinitionHolderBeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);// 根据proxyMode的值,选择是否创建作用域代理definitionHolder =AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);beanDefinitions.add(definitionHolder);// 注册beanDefinitionregisterBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}
registerComponents
这个方法一共做两件事:
- 将上一步获取到的所有BeanDefinition添加到compositeDef的nestedComponents属性中。
- 判断属性annotation-config值(默认为true),如果为true,则调用AnnotationConfigUtils.registerAnnotationConfigProcessors方法。
protected void registerComponents(XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {Object source = readerContext.extractSource(element);// 使用注解的tagName和source构建CompositeComponentDefinitionCompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);// 将扫描到的所有beanDefinition添加到compositeDef的nestedComponents属性中for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));}// Register annotation config processors, if necessary.boolean annotationConfig = true;if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {// 获取component-scan标签的annotation-config属性值,默认为trueannotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));}if (annotationConfig) {// 如果annotation-config属性值为true,在给定的注册表中注册所有用于注解的bean后置处理器Set<BeanDefinitionHolder> processorDefinitions =AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);for (BeanDefinitionHolder processorDefinition : processorDefinitions) {// 将注册的注解后置处理器的BeanDefinition添加到compositeDef的nestedComponents属性中compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));}}// 触发组件注册事件,默认实现为EmptyReaderEventListenerreaderContext.fireComponentRegistered(compositeDef);}
核心方法 AnnotationConfigUtils.registerAnnotationConfigProcessors
经过了前面一系列的加载、铺垫,此时终于来到了核心方法,来看看ConfigurationClassPostProcessor是如何进行创建的。
AnnotationConfigUtils类中有许多的常量值,而代码中会进行判断,如果没有该BeanDefinition,则会进行创建,而创建的正是ConfigurationClassPostProcessor.class。
源码片段
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {//省略部分源码....
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalConfigurationAnnotationProcessor";// 创建BeanDefinitionHolder集合Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 注册内部管理的用于处理@configuration注解的后置处理器的beanif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);// 注册BeanDefinition到注册表中beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}return beanDefs;}
完整方法
会在类型进行多个常量判断,如果BeanDefinition中不包含该类,则创建并封装到BeanDefinition中。
public abstract class AnnotationConfigUtils {/*** The bean name of the internally managed Configuration annotation processor.*/public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalConfigurationAnnotationProcessor";/*** The bean name of the internally managed BeanNameGenerator for use when processing* {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext}* and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make* any custom name generation strategy available to the underlying* {@link ConfigurationClassPostProcessor}.* @since 3.1.1*/public static final String CONFIGURATION_BEAN_NAME_GENERATOR ="org.springframework.context.annotation.internalConfigurationBeanNameGenerator";/*** The bean name of the internally managed Autowired annotation processor.*/public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalAutowiredAnnotationProcessor";/*** The bean name of the internally managed Required annotation processor.* @deprecated as of 5.1, since no Required processor is registered by default anymore*/@Deprecatedpublic static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalRequiredAnnotationProcessor";/*** The bean name of the internally managed JSR-250 annotation processor.*/public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalCommonAnnotationProcessor";/*** The bean name of the internally managed JPA annotation processor.*/public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME ="org.springframework.context.annotation.internalPersistenceAnnotationProcessor";private static final String PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME ="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor";/*** The bean name of the internally managed @EventListener annotation processor.*/public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME ="org.springframework.context.event.internalEventListenerProcessor";/*** The bean name of the internally managed EventListenerFactory.*/public static final String EVENT_LISTENER_FACTORY_BEAN_NAME ="org.springframework.context.event.internalEventListenerFactory";/*** Register all relevant annotation post processors in the given registry.* @param registry the registry to operate on* @param source the configuration source element (already extracted)* that this registration was triggered from. May be {@code null}.* @return a Set of BeanDefinitionHolders, containing all bean definitions* that have actually been registered by this call*/public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {// 获取beanFactoryDefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {// //设置依赖比较器beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {// //设置自动装配解析器beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}// 创建BeanDefinitionHolder集合Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 注册内部管理的用于处理@configuration注解的后置处理器的beanif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);// 注册BeanDefinition到注册表中beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注册内部管理的用于处理@Autowired,@Value,@Inject以及@Lookup注解的后置处理器beanif (!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.// 注册内部管理的用于处理JSR-250注解,例如@Resource,@PostConstruct,@PreDestroy的后置处理器beanif (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.// 注册内部管理的用于处理JPA注解的后置处理器beanif (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));}// 注册内部管理的用于处理@EventListener注解的后置处理器的beanif (!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));}// 注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象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;}
}
截止到这,从xml文件的加载到context 标签 component-scan属性的解析的整体流程已经介绍完成,
接下来看下费尽周折创建的ConfigurationClassPostProcessor中到底有什么?
ConfigurationClassPostProcessor
可以看到ConfigurationClassPostProcessor 实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered。
正好呼应上了上一篇所讲的内容,所以当调用beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class)时。
一定可以获取到Spring已经创建了的ConfigurationClassPostProcessor,并且也一定会调用对应的postProcessBeanDefinitionRegistry();方法。
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {//省略部分源码。。。。/*** 定位、加载、解析、注册相关注解** Derive further bean definitions from the configuration classes in the registry.*/@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {// 根据对应的registry对象生成hashcode值,此对象只会操作一次,如果之前处理过则抛出异常int registryId = System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}// 将马上要进行处理的registry对象的id值放到已经处理的集合对象中this.registriesPostProcessed.add(registryId);// 处理配置类的bean定义信息processConfigBeanDefinitions(registry);}
}
下一篇帖子介绍ConfigurationClassPostProcessor类的postProcessBeanDefinitionRegistry()方法都干了些什么。