Configuration涉及的FullLite模式

编程入门 行业动态 更新时间:2024-10-12 05:44:08

Configuration涉及的FullLite<a href=https://www.elefans.com/category/jswz/34/1771241.html style=模式"/>

Configuration涉及的FullLite模式

前提:使用注解@Configuration是为了提前初始化一批特性,不要将其作为@Component注解特性使用。

class ConfigurationClassParser {protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass){...// 处理注解 @ComponentScan,即启动类@ComponentScan存在的所有属性AnnotationMetadata am = sourceClass.getMetadata();Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(am, ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(am, ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {String className = sourceClass.getMetadata().getClassName();//通过启动类获取到扫描路径,即启动类所在的路径以及该路径下所有的子路径Set<BeanDefinitionHolder> scannedBeanDefinitions = componentScanParser.parse(componentScan, className);// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand == null) {bdCand = holder.getBeanDefinition();}// 确定候选类的模式Full or Liteif (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}...return null;}
}

1、获取@Configuration候选类

public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {protected Set<BeanDefinitionHolder> doScan(String... basePackages) {Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();for (String basePackage : basePackages) {//basePackages就是启动类所在的路径以及其子路径// 利用类加载器获取路径basePackage下所有候选类的资源URL~ResourceSet<BeanDefinition> candidates = findCandidateComponents(basePackage);for (BeanDefinition candidate : candidates) {ScopeMetadata sm = this.scopeMetadataResolver.resolveScopeMetadata(candidate);candidate.setScope(sm.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)) {// 确保容器注册表中只能存在当前bean唯一的BeanDefinitionBeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(sm, definitionHolder, registry);beanDefinitions.add(definitionHolder);registerBeanDefinition(definitionHolder, this.registry);}}}return beanDefinitions;}
}

每个候选类初始被封装成ScannedGenericBeanDefinition,核心属性就是候选类的资源URL~Resource。但是在添加容器注册表之前为啥进一步封住成BeanDefinitionHolder?

2、容器注册表注册候选类的BeanDefinition

public abstract class BeanDefinitionReaderUtils {//registry:DefaultListableBeanFactorypublic static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry){String beanName = definitionHolder.getBeanName();registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}
}

3、确定候选类的模式之Full or Lite

abstract class ConfigurationClassUtils {public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory msf) {...AnnotationMetadata metadata;String className = (AnnotatedBeanDefinition) beanDef).getMetadata().getClassName();if (beanDef instanceof AnnotatedBeanDefinition && className.equals(className)) {metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();}else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||BeanPostProcessor.class.isAssignableFrom(beanClass) ||AopInfrastructureBean.class.isAssignableFrom(beanClass) ||EventListenerFactory.class.isAssignableFrom(beanClass)) {return false;}metadata = AnnotationMetadata.introspect(beanClass);}else {MetadataReader metadataReader = msf.getMetadataReader(className);metadata = metadataReader.getAnnotationMetadata();}Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());//查看候选类中属性proxyBeanMethods,默认值为trueif (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {// 如果proxyBeanMethods = true则为Full默认beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);}else if (config != null || isConfigurationCandidate(metadata)) {//否则为Lite模式beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);}else {return false;}...return true;}
}

4、候选类尝试Cglib代理处理

final class PostProcessorRegistrationDelegate {public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> bp) {...// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear....// Now, invoke the postProcessBeanFactory callback of all processors handled so far.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(bp, beanFactory);}...}private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {for (BeanFactoryPostProcessor postProcessor : postProcessors) {// ConfigurationClassPostProcessorpostProcessor.postProcessBeanFactory(beanFactory);}}
}
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {int factoryId = System.identityHashCode(beanFactory);this.factoriesPostProcessed.add(factoryId);if (!this.registriesPostProcessed.contains(factoryId)) {// BeanDefinitionRegistryPostProcessor hook apparently not supported...// Simply call processConfigurationClasses lazily at this point then.processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);}enhanceConfigurationClasses(beanFactory);beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));}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);...if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) {// Full模式...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// org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClassbeanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);// Set enhanced subclass of the user-specified bean classClass<?> configClass = beanDef.getBeanClass();//候选类生成最终Cglib代理类Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);if (configClass != enhancedClass) {beanDef.setBeanClass(enhancedClass);}}}
}

更多推荐

Configuration涉及的FullLite模式

本文发布于:2023-11-15 19:46:04,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1605269.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   Configuration   FullLite

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!