@Configuration注解 -【Spring底层原理】

BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;

registryProcessor.postProcessBeanDefinitionRegistry(registry);

registryProcessors.add(registryProcessor);

} else {

regularPostProcessors.add(postProcessor);

}

}

currentRegistryProcessors = new ArrayList();

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

String[] var16 = postProcessorNames;

var9 = postProcessorNames.length;

int var10;

String ppName;

// 遍历postProcessorNames

for(var10 = 0; var10 < var9; ++var10) {

ppName = var16[var10];

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

sortPostProcessors(currentRegistryProcessors, beanFactory);

registryProcessors.addAll(currentRegistryProcessors);

// 解析配置类,为配置中的bean定义生成对应beanDefinition,并注入到registry的beanDefinitionMap

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

currentRegistryProcessors.clear();

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

var16 = postProcessorNames;

var9 = postProcessorNames.length;

for(var10 = 0; var10 < var9; ++var10) {

ppName = var16[var10];

if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

sortPostProcessors(currentRegistryProcessors, beanFactory);

registryProcessors.addAll(currentRegistryProcessors);

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

currentRegistryProcessors.clear();

boolean reiterate = true;

while(reiterate) {

reiterate = false;

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

String[] var19 = postProcessorNames;

var10 = postProcessorNames.length;

for(int var26 = 0; var26 < var10; ++var26) {

String ppName = var19[var26];

if (!processedBeans.contains(ppName)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

reiterate = true;

}

}

sortPostProcessors(currentRegistryProcessors, beanFactory);

registryProcessors.addAll(currentRegistryProcessors);

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

currentRegistryProcessors.clear();

}

// 调用ConfigurationClassPostProcessor#postProcessBeanFactory增强配置类

// 通过cglib生成增强类,加载到jvm内存

// 设置beanDefinition的beanClass为增强类,让@Bean生成的bean是单例

invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);

invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

} else {

invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

}

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

regularPostProcessors = new ArrayList();

registryProcessors = new ArrayList();

currentRegistryProcessors = new ArrayList();

postProcessorNames = postProcessorNames;

int var20 = postProcessorNames.length;

String ppName;

for(var9 = 0; var9 < var20; ++var9) {

ppName = postProcessorNames[var9];

if (!processedBeans.contains(ppName)) {

if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));

} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

registryProcessors.add(ppName);

} else {

currentRegistryProcessors.add(ppName);

}

}

}

sortPostProcessors(regularPostProcessors, beanFactory);

invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

List orderedPostProcessors = new ArrayList(registryProcessors.size());

Iterator var21 = registryProcessors.iterator();

while(var21.hasNext()) {

String postProcessorName = (String)var21.next();

orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

}

sortPostProcessors(orderedPostProcessors, beanFactory);

invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

List nonOrderedPostProcessors = new ArrayList(currentRegistryProcessors.size());

Iterator var24 = currentRegistryProcessors.iterator();

while(var24.hasNext()) {

ppName = (String)var24.next();

nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));

}

invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

beanFactory.clearMetadataCache();

}

这里和@Configuration注解相关的方法是invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);,继续跟踪,进入源码查看:

PostProcessorRegistrationDelegateinvokeBeanFactoryPostProcessors方法】

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

Iterator var2 = postProcessors.iterator();

while(var2.hasNext()) {

BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();

StartupStep var10000 = beanFactory.getApplicationStartup().start(“spring.context.bean-factory.post-process”);

postProcessor.getClass();

StartupStep postProcessBeanFactory = var10000.tag(“postProcessor”, postProcessor::toString);

// 调用ConfigurationClassPostProcessor#postProcessBeanFactory增强配置类

postProcessor.postProcessBeanFactory(beanFactory);

postProcessBeanFactory.end();

}

}

继续跟踪postProcessor.postProcessBeanFactory(beanFactory);,进入源码查看,发现是一个接口,咱们找到和@Configuration相关的,也就是截图中框出来的 ,查看源码:

image-20210115154241215

image-20210115154241215

ConfigurationClassPostProcessor类中postProcessBeanFactory方法】

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);

} else {

this.factoriesPostProcessed.add(factoryId);

if (!this.registriesPostProcessed.contains(factoryId)) {

this.processConfigBeanDefinitions((BeanDefinitionRegistry)beanFactory);

}

// 进行代理,为@Configuration注解的类生成增强类

this.enhanceConfigurationClasses(beanFactory);

beanFactory.addBeanPostProcessor(new ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor(beanFactory));

}

}

该方法会去判断我们的bean工厂当中是否有bean需要进行cglib代理,并在enhanceConfigurationClasses(beanFactory)方法中进行代理,为@Configuration注解的类生成增强类,继续跟踪,点进enhanceConfigurationClasses,如下:

ConfigurationClassPostProcessor类中enhanceConfigurationClasses方法】

public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {

StartupStep enhanceConfigClasses = this.applicationStartup.start(“spring.context.config-classes.enhance”);

Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap();

String[] var4 = beanFactory.getBeanDefinitionNames();

int var5 = var4.length;

for(int var6 = 0; var6 < var5; ++var6) {

String beanName = var4[var6];

BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);

// 在ConfigurationClassUtils中标记是Full @Configuration还是lite @Bean mode

Object configClassAttr = beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE);

MethodMetadata methodMetadata = null;

if (beanDef instanceof AnnotatedBeanDefinition) {

methodMetadata = ((AnnotatedBeanDefinition)beanDef).getFactoryMethodMetadata();

}

if ((configClassAttr != null || methodMetadata != null) && beanDef instanceof AbstractBeanDefinition) {

AbstractBeanDefinition abd = (AbstractBeanDefinition)beanDef;

if (!abd.hasBeanClass()) {

try {

abd.resolveBeanClass(this.beanClassLoader);

} catch (Throwable var13) {

throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), var13);

}

}

}

// 1.判断是否是全类注解

if (“full”.equals(configClassAttr)) {

if (!(beanDef instanceof AbstractBeanDefinition)) {

throw new BeanDefinitionStoreException(“Cannot enhance @Configuration bean definition '” + beanName + “’ since it is not stored in an AbstractBeanDefinition subclass”);

}

if (this.logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {

this.logger.info(“Cannot enhance @Configuration bean definition '” + beanName + “’ since its singleton instance has been created too early. The typical cause is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor return type: Consider declaring such methods as ‘static’.”);

}

// 2.是全注解则将beandefinition放入map中

configBeanDefs.put(beanName, (AbstractBeanDefinition)beanDef);

}

}

if (!configBeanDefs.isEmpty() && !IN_NATIVE_IMAGE) {

ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();

Iterator var15 = configBeanDefs.entrySet().iterator();

// 3.然后遍历这个map

while(var15.hasNext()) {

Entry<String, AbstractBeanDefinition> entry = (Entry)var15.next();

AbstractBeanDefinition beanDef = (AbstractBeanDefinition)entry.getValue();

beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);

Class<?> configClass = beanDef.getBeanClass();

// 4.进行cglib代理,为@Configuration注解的类生成增强类

Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

if (configClass != enhancedClass) {

if (this.logger.isTraceEnabled()) {

this.logger.trace(String.format(“Replacing bean definition ‘%s’ existing class ‘%s’ with enhanced class ‘%s’”, entry.getKey(), configClass.getName(), enhancedClass.getName()));

}

// 再通过beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass属性,

// 在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来

// 所以最终实例化出来的@Configuration bean是一个代理类的实例

beanDef.setBeanClass(enhancedClass);

}

}

enhanceConfigClasses.tag(“classCount”, () -> {

return String.valueOf(configBeanDefs.keySet().size());

}).end();

} else {

enhanceConfigClasses.end();

}

}

ConfigurationClassUtils类中声明了是Full @Configuration还是lite @Bean mode,可以看看源码:

ConfigurationClassUtils类中checkConfigurationClassCandidate方法】

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());

// 如果存在@Configuration注解,则为BeanDefinition设置configurationClass属性为full

if (config != null && !Boolean.FALSE.equals(config.get(“proxyBeanMethods”))) {

beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, “full”);

} else {

if (config == null && !isConfigurationCandidate(metadata)) {

return false;

}

// 如果没有@Configuration注解或者有Component,ComponentScan,Import,ImportResource 注解中的任意一个,

// 或者存在 被@bean 注解的方法,则返回true.

// 则设置configurationClass属性为lite

beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, “lite”);

}

Integer order = getOrder(metadata);

if (order != null) {

beanDef.setAttribute(ORDER_ATTRIBUTE, order);

}

跟踪到这里,基本上就比较明朗了,可以得到我们想要的答案

  1. ConfigurationClassUtils类中的checkConfigurationClassCandidate标记是Full @Configuration还是lite @Bean mode
  1. 通过"full".equals(configClassAttr)判断是否是全类注解
  1. 是全注解则将beandefinition放入map中configBeanDefs.put
  1. 遍历这个map
  1. 使用cglib技术为配置类生成一个enhancedClass
  1. 通过enhancer.enhance进行cglib代理,为@Configuration注解的类生成增强类
  1. 再通过beanDef.setBeanClass(enhancedClass)修改beanDefinition的BeanClass属性,在bean实例化阶段,会利用反射技术将beanClass属性对应的类实例化出来,所以最终实例化出来的@Configuration bean是一个代理类的实例

使用了@Configuration注解的类,属于Full @Configuration。@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系,保证@Bean的对象作用域受到控制,避免多例。@Configuration类中的@Bean地方会被CGLIB进行代理。Spring会拦截该方法的执行,在默认单例情况下,容器中只有一个Bean,所以我们多次调用user()方法,获取的都是同一个对象。

对于@Configuration注解的类中@Bean标记的方法,返回的都是一个bean,在增强的方法中,Spring会先去容器中查看一下是否有这个bean的实例了,如果有了的话,就返回已有对象,没有的话就创建一个,然后放到容器中。

是如何进行代理的,咱们还可以继续跟踪:点开enhancer.enhance,进入ConfigurationClassEnhancer类,在这个类中会去执行cglib代理类中的代理方法,如下:

ConfigurationClassEnhancer类中static静态方法】

static {

CALLBACKS = new Callback[]{new ConfigurationClassEnhancer.BeanMethodInterceptor(),

new ConfigurationClassEnhancer.BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE};

CALLBACK_FILTER = new ConfigurationClassEnhancer.ConditionalCallbackFilter(CALLBACKS);

logger = LogFactory.getLog(ConfigurationClassEnhancer.class);

objenesis = new SpringObjenesis();

}

cglib代理主要就是callBacks中的方法,点进去可以看到是一个接口,其中有一个实现类就是和cglib相关的

image-20210115201141656

image-20210115201141656

四、总结


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

img

面试资料整理汇总

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

成功从小公司跳槽进蚂蚁定级P7,只因刷了七遍这些面试真题

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(资料价值较高,非无偿)

img

面试资料整理汇总

[外链图片转存中…(img-fqeowZnt-1711575637975)]

[外链图片转存中…(img-YyKpPxHa-1711575637975)]

这些面试题是我朋友进阿里前狂刷七遍以上的面试资料,由于面试文档很多,内容更多,没有办法一一为大家展示出来,所以只好为大家节选出来了一部分供大家参考。

面试的本质不是考试,而是告诉面试官你会做什么,所以,这些面试资料中提到的技术也是要学会的,不然稍微改动一下你就凉凉了

在这里祝大家能够拿到心仪的offer!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 22
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值