前言
此文介绍spring关于@Configuration的冷门知识(很少人知道,知道了其实也没多大的用处,本人理解的也很肤浅, 文章仅为介绍, 有兴趣的同学可以深入源码了解)
演示版本
jdk: 1.8
spring: 5.2.7.RELEASE
参考 :
spring中文文档: https://github.com/DocsHome/spring-docs/blob/master/SUMMARY.md
正文
本文默认大家都对spring有一定的了解, 基础知识就不太多介绍了, 直接讲@Configuration与其他注解(如 @Component,@Service...)的区别
spring官方管这两种模式分别叫:Full @Configuration和lite @Bean mode
中文手册介绍:

本次演示采用注解方式启动spring容器, xml也是可以的(xml个人很久没有配置了, 并不是很熟练), 用注解方式大家可以直接copy代码到搭好的spring或springboot项目中直接启动就可以了
直接上代码演示
A.java
public class A {
public A (){
System.out.println("A 被创建了...");
}
}
B.java
public class B {
public B (){
System.out.println("B 被创建了...");
}
}
Test.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Component
//@Configuration
public class Test {
@Bean
public A a(){
//当类上注解为@Component时idea可能会出现提示但不会阻止代码编译运行, idea还是很nice的
b();
return new A();
}
@Bean
public B b(){
return new B();
}
}
运行spring容器, 大家可以自行搭建, 我这个配置类啥也没干,只是做了一个@Configuration和配置包扫描路径, 确保我们的Test类能被spring扫描到


控制台输出 控制台B被创建了两次, 通过debug我们可以看到, Test是一个原生的类


接下来我们把Test的注解换成@Configuration 再试一下. 看看会不会有不同的效果
修改注解--运行

神奇的事发生了, Test类变成了CGLIB代理类, 机智的同学肯定也看了控制台, B只被创建了一次.
到这里我们已经简单了解了关于@Configuration与@Component之间的区别(当然还有更多的区别部分后面会分享到)
我们来深追一下spring源码吧!
源码相关类: org.springframework.context.annotation.ConfigurationClassUtils

org.springframework.context.annotation.ConfigurationClassUtils#checkConfigurationClassCandidate

当我们解析Test的时候(Test类上带了@Configuration注解),会给它的一个属性标识为Full,其他的标识为Lite
proxyBeanMethods 是@Configuration注解的一个属性, 默认值为true, 表示配置类是否需要被代理

然后在我们调用ConfigurationClassPostProcessor.postProcessBeanFactory()方法的时候会去判断我们的bean工厂当中是否有bean需要进行cglib代理。


对源码熟悉的同学可以应该可以找到入口, 找不到也可以通过截图打断点反推, 这里我画一下简单的执行流程到解析

个人理解, @Configuration就是为了让我们在编写业务代码的时候,将组件类型更细化区分
对于我们要引入完整的帮助类(),或者引入框架中的组件如 spring的后置处理器扩展, 监听器等等我们可以用@Component
而对于要解析外部依赖,注入bean和解析配置映射等关系时,我们可以用@Configuration标识该组件是配置类型的组件
相关总结-来源网络
// 当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResource注解,称之为Lite配置类
// 如果加了Configuration注解,就称之为Full配置类
// 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类
// 如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了
// 如果配置类是Full配置类(即cgilb代理类),在类中@Bean只会被创建一次. 如两个@Bean相互调用, 只会创建一次
本文仅抛砖引玉, 更多用法和区别请参考 https://blog.csdn.net/demon7552003/article/details/107988310 (当然看其他相关的介绍也是可以的)
更过细节需要深入看源码, 本人对spring源码还只是入门阶段, 就不班门弄斧了.有兴趣的同学可以自己深入源码总结
本文探讨了Spring @Configuration注解的Full和Lite模式的区别,通过代码示例展示了@Configuration如何影响类的实例化。当使用@Configuration时,类会被CGLIB代理,而@Component则不会。文章鼓励读者深入源码理解更多细节。
1208

被折叠的 条评论
为什么被折叠?



