@ComponentScan
使用@Configuration
和@Component
创建bean。这两个注释在交换时都可以正常工作。那么它们之间有什么区别呢?
@ComponentScan
使用@Configuration
和@Component
创建bean。这两个注释在交换时都可以正常工作。那么它们之间有什么区别呢?
@Configuration也是一个@Component,但@Component不能像@Configuration那样起作用。
@Bean
也可以在@Component
类中声明(或者换句话说,链接的Javadoc的第一句话至多是误导性的)。 - Martin Andersson它们之间有非常微妙的差别。让我提供一个非常快速的概述。
考虑以下情况:
@Configuration
public class MyConfig {
@Bean
public ServiceA aService(){
return new ServiceA();
}
@Bean
public ServiceB bService(){
return new ServiceB(aService());
}
}
请注意,ServiceB
bean 依赖于 ServiceA
,并且这不是自动装配。相反,它的编写方式意味着创建了一个新实例,而这实际上并非由 Spring 创建。而是由程序员使用 new
关键字创建的。
因此,如果我们使用 @Configuration
,则它将使用 CGLIB 代理,并在这种情况下创建由 Spring 管理的单例 bean。如果您多次调用它,则返回 Spring 创建的相同 bean - 类似于自动装配的效果。
而使用 @Component
,它不会进行代理处理,而是每次调用该方法时都会简单地返回一个新实例,而不是提供 Spring 管理的实例。(请记住,Spring Bean 是由 Spring 容器管理的内容,作为开发人员,您的工作是使用 @Autowired
等方法引入它们)。
通过 @Configuration(proxyEnabled=false)
可以实现与 @Component
相同的效果(这也称为轻量级模式处理)。因此,在轻量级模式下,您最终会执行以下操作:
@Configuration(proxyEnabled = false) // Lite mode, same effect as @Component
public class MyConfig {
@Bean
public ServiceA aService() {
return new ServiceA();
}
@Autowired
@Bean
public ServiceB bService(ServiceA aServiceBean){
return new ServiceB(aServiceBean);
}
}
希望对你有所帮助!祝你编码愉快!
proxyBeanMethods
而不是proxyEnabled
吗? - Sany LiewproxyBeanMethods
而不是proxyEnabled
吗? - undefined实际上,答案不完整。@Component表示一个被注解的类是一个“组件”。这样的类在使用基于注解的配置和类路径扫描进行自动检测时会被视为候选对象。
但是你可以创建一个名为MyConfiguration.java的类并将其用@Component
标记,然后在其中添加@Beans
声明。这样它看起来就像一个配置文件,主要区别在于当使用@Configuration
注解类时,@Bean
注解方法会使用CGLIB进行代理,代理代码在第一次调用方法返回bean之后,会再次调用该方法以返回上下文中的bean,而不是再次执行方法创建另一个实例(这是使用@Component和@Bean时发生的情况)。
@Component
和@Bean
而不是@Configuration
和@Bean
吗?前者是否与并行有关? - Treefish Zhang@Component
和@Configuration
两种方式,但都没有执行@Bean
方法超过一次。 - Wit@Configuration - 它类似于 beans.xml,但是基于 Java 的 bean 配置。这意味着用此注解注释的类是配置 bean 的地方,并且将成为自动检测的候选对象。在此类中,使用 @Bean 注解标记方法,以返回该类的对象。
示例:
@Configuration
public class ConfigClass {
@Bean
public UserClass getObject() {
return new UserClass();
}
}
@Component - 如果一个类没有被标记为@Component,那么你就不能使用@Autowired来自动装配任何该类的实例。这意味着当你想要使用注解来自动装配任何类时,应该将该类注释为@Component。
示例:
@Component
public class A { .... }
public class B {
@Autowired
A a;
.....
.....
}
@Component
的第二个声明需要澄清,因为它现在并不完全正确。@Autowire
标记字段/参数以通过Spring bean实例由框架注入。然而,@Component
仅标记类以通过组件扫描自动检测(顺便说一下,还有其他各种标记注释),这并不是必需的。Bean实例可以通过其他方式创建,例如通过@Configuration
类、工厂、通过xml配置进行声明等。 - Pawel Zieminski@Configuration
会默认导入 @Component
。Controller、Service 和 Repository 是子组件(与 Configuration 一起),它们也是自动检测的候选对象。
@Configuration
和@Component
都是Spring框架中使用的注释,但它们的作用不同。
@Configuration
是一种类型级别的注释,表示一个类声明了一个或多个@Bean
方法,并且可能被Spring容器处理,以在运行时生成bean定义和这些bean的服务请求。通常,带有@Configuration
注释的类用作bean定义的来源。
@Component
是一种类级别的注释,指示已注释的类为“组件”。当使用基于注释的配置和类路径扫描时,这些类将被视为自动检测的候选项。它是任何由Spring管理的组件或bean的通用原型。
简单地说,@Configuration
用于定义bean及其依赖关系,而@Component
用于通用目的的组件自动检测。
在大多数情况下,您会使用@Configuration
来定义复杂配置的bean,使用@Component
定义整个应用程序中经常使用的简单bean。
以下是一些官方参考资料,您可能会发现有帮助:
Spring框架文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-java
@Configuration
JavaDoc:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/context/annotation/Configuration.html
@Component
JavaDoc:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/stereotype/Component.html
@Bean
方法,可以被Spring容器处理以在运行时生成bean定义和服务请求。@Configuration
类,你会发现它是用@Component
元注释进行元注释的。@Target(value=TYPE)
@Retention(value=RUNTIME)
@Documented
@Component
public @interface Configuration
@Bean
允许我们以任何方式定义依赖项,这就是为什么 @Bean
注解在方法上方,我们手动创建一个 bean 对象并从该方法中返回它的原因。 @Component
允许我们快速定义依赖项,这就是为什么 @Component
放在类的上方。我们只在需要时注入它。综上所述,这三点意味着- 要快速定义一个 bean,我们可以使用 @Component
注释进行类注释。要按照我们的喜好定义 bean(支持自定义要求),我们可以在 @Configuration
注释的类中使用 @Bean
编写 bean 定义。
除了reos指出的差异之外。
@Configuration不能被@Component替换的原因如下:
区别在于如何处理bean之间的依赖关系。 请参考以下链接,了解详细的解释和示例: Configuration和Component之间的区别
@Configuration
的记忆化特性,就像上面@jcrada所提到的那样,但它并没有提到任何有关处理bean之间依赖关系的内容。 - Shadow Man