跳至主要內容

Configuration 和 Component 的区别

Mr.Hope...小于 1 分钟

结论

Spring 注解中 @Configuration 和 @Component 的区别总结为一句话就是:

@Configuration 中所有带 @Bean 注解的方法都会被动态代理(cglib),因此调用该方法返回的都是同一个实例。而 @Conponent 修饰的类不会被代理,每实例化一次就会创建一个新的对象

在 @Configuration 注解的源代码中,使用了 @Component 注解:

image-20240428101133912
image-20240428101133912

从定义来看, @Configuration 注解本质上还是 @Component,因此 <context:component-scan/> 或者 @ComponentScan 都能处理 @Configuration 注解的类。

代码示例

public class Hello {
    private String name;
}
@Component
public class MyComponent {
    @Bean
    public Hello componentHello(){
        return new Hello();
    }
}
@Configuration
public class MyConfig {
    @Bean
    public Hello configHello(){
        return new Hello();
    }
}
public class Main {

    public static void main(String[] args) {
        // 创建和初始化容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);

        // 容器中的hello
        MyConfig myConfig = context.getBean("myConfig",MyConfig.class);
        Hello configBeanHello = context.getBean("configHello",Hello.class);
        // 比较myConfig容器的对象
        System.out.println(myConfig.configHello());
        System.out.println(configBeanHello);
        System.out.println("===================================");
        // 比较myComponent容器中的对象
        AnnotationConfigApplicationContext contextCom = new AnnotationConfigApplicationContext(MyComponent.class);
        MyComponent myComponent = contextCom.getBean("myComponent",MyComponent.class);
        Hello componentBeanHello =  contextCom.getBean("componentHello",Hello.class);
        System.out.println(myComponent.componentHello());
        System.out.println(componentBeanHello);

    }
}

运行结果

image-20240428104421335
image-20240428104421335

可以看到@Configuration注解返回的bean对象是同一个对象,@Component注解返回的是不同的对象。