You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@Bean在@Configuration与@Component中的区别及实例数量探究

@Configuration vs @Component 中的@Bean:差异与实例数量解析

嘿,这个问题问到点子上了!很多Spring开发者刚接触这两种Bean声明方式时,都会被CGLIB代理带来的差异搞懵,我来给你拆解清楚:

核心差异:CGLIB代理的影响

  • @Configuration类的特殊处理:
    Spring会给标注了@Configuration的类生成一个CGLIB代理子类。当你在这个类的@Bean方法里调用其他@Bean方法时,代理会拦截这个调用,直接返回Spring容器中已经存在的Bean实例(默认单例),而不是执行方法创建新对象。

  • @Component类的普通处理:
    标注@Component的类不会被Spring自动生成CGLIB代理(除非你手动开启了其他代理模式),里面的@Bean方法就是普通的Java方法。如果在同一个@Component类里调用@Bean方法,每次调用都会执行方法体,创建一个全新的实例,和Spring容器中管理的那个实例完全无关。

实例数量对比(默认单例Scope)

1. @Configuration场景

不管你在@Configuration类内部调用多少次@Bean方法,每个@Bean对应的类只会生成1个实例。因为所有的@Bean方法调用都会被代理拦截,复用容器中已有的单例对象。

举个代码例子:

@Configuration
public class AppConfig {
    @Bean
    public User user() {
        return new User("Alice");
    }

    @Bean
    public Order order() {
        // 这里调用user(),返回的是容器里的同一个User实例
        return new Order(user());
    }
}

运行后,Spring容器中只会有1个User实例和1个Order实例,Order依赖的User就是容器里的那个单例。

2. @Component场景

这种情况要分两种情况看:

  • Spring容器初始化时,会调用@Bean方法创建1个实例并放入容器中;
  • 如果@Component类的实例(本身也是Spring管理的单例)内部调用@Bean方法,每次调用都会生成一个新的实例。

还是用代码举例:

@Component
public class ComponentBean {
    @Bean
    public User user() {
        return new User("Bob");
    }

    @Bean
    public Order order() {
        // 这里调用user(),会创建一个新的User实例,和容器里的那个不是同一个
        return new Order(user());
    }
}

运行后,Spring容器里有1个User实例(初始化时创建的)和1个Order实例,但Order里的User是调用user()方法新创建的,所以User总共有2个实例,Order有1个。如果后续ComponentBean的其他方法再调用user(),还会继续生成新的User实例。

总结一下

维度@Configuration中的@Bean@Component中的@Bean
是否被CGLIB代理是(自动生成代理类)否(默认无代理)
内部@Bean方法调用复用容器单例实例每次调用创建新实例
默认单例下实例数量每个@Bean对应1个实例容器1个 + 内部调用n个

内容的提问来源于stack exchange,提问作者user9328991

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:08:37