配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(下)

简介: 配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(下)

proxyBeanMethods属性的作用


proxyBeanMethods属性是Spring 5.2.0版本为@Configuration注解新增加的一个属性:


@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
  @AliasFor(annotation = Component.class)
  String value() default "";
  // @since 5.2
  boolean proxyBeanMethods() default true;
}


它的作用是:是否允许代理@Bean方法。说白了:决定此配置使用Full模式还是Lite模式。为了保持向下兼容,proxyBeanMethods的默认值是true,使用Full模式配置。


Spring 5.2提出了这个属性项,是期望你在已经了解了它的作用之后,显示的把它置为false的,因为在云原生将要到来的今天,启动速度方面Spring一直在做着努力,也希望你能配合嘛。这不Spring Boot就“配合”得很好,它在2.2.0版本(依赖于Spring 5.2.0)起就把它的所有的自动配置类的此属性改为了false,即@Configuration(proxyBeanMethods = false)。


Full模式/Lite模式实现上的差异


由于Spring 5.2.0新增了proxyBeanMethods属性来控制模式,因此实现上也有些许诧异,请各位注意甄别:


Spring 5.2.0+版本判断实现:


ConfigurationClassUtils:
    Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
    if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
    } else if (config != null || isConfigurationCandidate(metadata)) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    } else {
      return false;
    }


Spring 5.2.0-版本判断实现:


ConfigurationClassUtils:
    if (isFullConfigurationCandidate(metadata)) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
    } else if (isLiteConfigurationCandidate(metadata)) {
      beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
    } else {
      return false;
    }

思考题?


  1. 既然isConfigurationCandidate()判断方法是为checkConfigurationClassCandidate()服务,那Spring为何也把它设计为public static呢?
  2. ConfigurationClassUtils里还存在对@Order顺序的解析方法,不是说Spring的Bean是无序的吗?这又如何理解呢?


总结


本文作为上篇文章的续篇,解释了@Configuration配置的Full模式和Lite模式的判断原理,同时顺带的也介绍了什么叫主配置配和次配置类,这个概念(虽然官方并不这么叫)对你理解Spring Framework是非常有帮助的。如果你使用是基于Spring 5.2.0+的版本,在了解了这两篇文章内容的基础上,建议你的配置类均采用Lite模式去做,即显示设置proxyBeanMethods = false。


另外关于此部分内容,有些更为感兴趣的小伙伴问到:为什么Full模式下通过方法调用指向的仍旧是原来的Bean,保证了只会执行一次呢?开启的是Full模式这只是表象原因,想要回答此问题需要涉及到CGLIB增强实现的深水区内容,为了满足这些好奇(好学)的娃子,计划会在下篇文章继续再拿一篇专程讲解(预计篇幅不短,万字以上),你可订阅我的公众号持续保持关注。

相关文章
|
10月前
|
机器学习/深度学习 人工智能 自动驾驶
人工智能与就业市场:工作的变革
【10月更文挑战第31天】随着人工智能技术的飞速发展,就业市场正经历深刻变革。本文探讨了人工智能对就业市场的积极影响,如创造新兴职业、提高生产效率和促进职业转型,以及面临的挑战,如自动化取代部分工作、技能转型需求增加和就业市场两极分化。文章提出了加强教育培训、推动产业升级和创新、完善社会保障体系等应对策略,旨在为读者提供全面而深入的理解。
|
算法 BI 数据库
MyBatisPlus查询条件设置、映射匹配兼容性、id生成策略、多数据操作
MyBatisPlus查询条件设置、映射匹配兼容性、id生成策略、多数据操作
707 3
|
机器学习/深度学习 监控 算法框架/工具
用Python实现简单的图像分类器
用Python实现简单的图像分类器
263 0
|
架构师 Java 容器
|
Java API
java 获取阴历日期公历日期转农历日期或者阳历日期转阴历日期
java 获取阴历日期公历日期转农历日期或者阳历日期转阴历日期
485 0
|
SpringCloudAlibaba NoSQL Java
1.1 w字,18 张图,彻底说透 springboot starter 机制
1.1 w字,18 张图,彻底说透 springboot starter 机制
950 1
1.1 w字,18 张图,彻底说透 springboot starter 机制
|
Java
解决:No appenders could be found for logger
解决:No appenders could be found for logger
720 0
|
存储 运维 NoSQL
Redisson可重入锁原理
Redisson提供的分布式锁是可重入的,它使用的是Hset命令和Hash数据结构。
Redisson可重入锁原理
|
JavaScript 前端开发 Serverless
如何用5分钟通过Vercel 部署一个接口测试工具
超详细的案例,跟着做完就完事儿了!
如何用5分钟通过Vercel 部署一个接口测试工具