@Configuration 和 @Component 的详细区别
Spring 注解中 @Configuration 和 @Component 的区别总结为一句话就是:
@Configuration 中所有带 @Bean 注解的方法都会被动态代理(cglib),因此调用该方法返回的都是同一个实例。而 @Conponent 修饰的类不会被代理,每实例化一次就会创建一个新的对象。
在 @Configuration 注解的源代码中,使用了 @Component 注解:
从定义来看, @Configuration 注解本质上还是 @Component,因此 <context:component-scan/> 或者 @ComponentScan 都能处理 @Configuration 注解的类。
下面我们通过一个例子来说明上述情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | // 使用@Configuration和@Bean注解创建Room实例和People实例,并注入进spring容器 @Configuration public class RoomPeopleConfig { @Bean public Room room() { Room room = new Room(); room.setId( 1 ); room.setName( "房间" ); room.setPeople(people()); // 在创建Room实例时,再调用一次People()创建一个People实例 return room; } @Bean public People people() { People people = new People(); people.setId( 1 ); people.setName( "小明" ); return people; } } // 下面是测试代码 @SpringBootTest @ContextConfiguration (classes = Application. class ) public class ConfigurationTests { @Autowired private Room room; @Autowired private People people; @Test public void test() { System.out.println(people == room.getPeople() ? "是同一个实例" : "不是同一个实例" ); } } |
输出结果:
如果将 @Configuration 换成 @Component ,则输出:
从上面的结果可以发现使用 @Configuration 时在 people 和 spring 容器之中的是同一个对象,而使用 @Component 时是不同的对象。这就是因为 @Configuration 使用了 cglib 动态代理,返回的是同一个实例对象。
虽然 @Component 注解也会当做配置类,但是并不会为其生成 CGLIB 代理 Class,所以在生成 room 对象时和生成 people 对象时调用 people( ) 方法执行了两次 new 操作,所以是不同的对象。当使用 @Configuration 注解时,生成当前对象的子类 Class,并对方法拦截,第二次调用 people()方法时直接从 BeanFactory 之中获取对象,所以得到的是同一个对象。
所以@Configuration注解就是为了避免用户显式地去调用@Bean方法,造成破坏了@Bean方法的bean的单例,而@Configuration注解能够做到这样避免用户显式调用@Bean方法的原理就是通过创建对应的配置类cglib代理对象去实现的!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
2021-03-08 分布式事务解决方案之2PC(二)
2021-03-08 分布式事务初始(一)