配置类角色
配置类可作为spring容器的启动入口,在类上加@Configuration注解,则表示这是一个配置类,通常会搭配@ComponontScan注解扫描包使用,springboot框架中的@SpringBootApplication注解也是基于此注解封装的,所以学习配置类加载是整个spring ioc的入口和重点。
spring的配置类分为两种,一种叫正式配置类,即加了@Configuration注解的,还有一种是非正式的配置类,即加了@Component、@ComponentScan、@Import、@ImportResource、@Bean注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
配置类作用
配置类作为程序的入口,可配置各种注解,如@ComponentScan-对指定包下的bean进行初始化(下文将着重写到spring是如何实现的),@EnableTransactionManagement-开启事务注解等。本文暂时只讲bean定义的初始化实现,其他注解比如EnableTransactionManagement会在后面章节提出。
配置类加载流程
1.注册解析配置类的后置处理器ConfigurationClassPostProcessor
ConfigurationClassPostProcessor属于spring的一个重要的初始化类,后面解析配置类讲用到。容器初始化的时候new AnnotatedBeanDefinitionReader()->AnnotationConfigUtils.registerAnnotationConfigProcessors,看到下面的set,初始化长度是8,该方法初始了8个beanFactory后置处理器,其中第一个就是配置类解析处理类。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* 向容器注册解析配置类的后置处理器ConfigurationClassPostProcessor
*
*/
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//其他后置处理器
if (!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));
}
if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (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));
}
if (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));
}
if (!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));
}
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;
}
2.准备@Compent注解,将该注解加入到自定义规则中
在上文的this()方法中,有一个this.scanner = new ClassPathBeanDefinitionScanner(this);点到registerDefaultFilters()方法中进去,发现里面
this.includeFilters.add(new AnnotationTypeFilter(Component.class));,在一个filter中加入了我们的@Compent,后面会用到
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
protected void registerDefaultFilters() {
//加入扫描我们的@Component的
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
...
}
3.读取配置类,转换成bean定义
配置类也是一个bean,所以也需要在进bean工厂之前转换成bean定义。转化入口如下,初始化容器的时候,有个register方法,就是注册配置类的方法,最终也会调用registerBeanDefinition方法。
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
//注册配置类
register(annotatedClasses);
refresh();
}
4.调用bean工厂后置处理器
该步骤很重要,我们在1步骤中注册了8个bean工厂的后置处理器,在这里开始调用,入口在AbstractApplicationContext.refresh()->AbstractApplicationContext.invokeBeanFactoryPostProcessors()->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
截取该方法一段,第一个if,判断了当前处理器是不是BeanDefinitionRegistryPostProcessor类型,而之前1步骤中注册的配置类处理器ConfigurationClassPostProcessor是该类型,所以调用ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()方法。
image.png
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {//若没有实现BeanDefinitionRegistryPostProcessor 接口,那么他就是BeanFactoryPostProcessor
regularPostProcessors.add(postProcessor);
}
}
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()方法,这里会循环所有的bean定义,将配置类加到候选configCandidates中,(Candidate英文翻译过来“候选”)候选配置类的标准在文章开头写了,下面两个if代表两种不同的配置类。
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));
}
}
5.解析配置类
拿到4步骤中的候选配置类后,就开始真正的解析配置类了,入口在ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()中会调用ConfigurationClassParser.parse()->ConfigurationClassParser.ddoProcessConfigurationClass(),第一行中拿到@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) {
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());
}
}
}
}
进入到ComponentScanAnnotationParser.parse(),
//设置CompentScan对象的includeFilters 包含的属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
然后调用ClassPathBeanDefinitionScanner.doScan方法,循环包
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
进入findCandidateComponents->scanCandidateComponents->isCandidateComponent(筛选候选Component),这里就会从2步骤中的过滤器规则中得到@Component,放入到bean定义集合中
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
6.配置类读取到的bean定义集合加载成bean定义
回到ConfigurationClassPostProcessor.processConfigBeanDefinitions方法中,调用this.reader.loadBeanDefinitions(configClasses);这里真正的把我们解析出来的配置类注册成bean定义
do {
parser.parse(candidates);
...
this.reader.loadBeanDefinitions(configClasses);
}
网友评论