前言:
现时兄弟们对“spring 动态配置”大概比较重视,兄弟们都想要知道一些“spring 动态配置”的相关内容。那么小编同时在网络上网罗了一些关于“spring 动态配置””的相关资讯,希望看官们能喜欢,看官们一起来学习一下吧!配置类角色
配置类可作为spring容器的启动入口,在类上加@Configuration注解,则表示这是一个配置类,通常会搭配@ComponontScan注解扫描包使用,springboot框架中的@SpringBootApplication注解也是基于此注解封装的,所以学习配置类加载是整个spring ioc的入口和重点。
spring的配置类分为两种,一种叫正式配置类,即加了@Configuration注解的,还有一种是非正式的配置类,即加了@Component、@ComponentScan、@Import、@ImportResource、@Bean注解
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Configurationpublic @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()方法。
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); }
标签: #spring 动态配置