我知道在第2.5版中引入了@Component
注释,以便通过使用类路径扫描来消除xml bean定义。
@Bean
是在3.0版本中引入的,可以与@Configuration
一起使用,以便完全摆脱xml文件并改为使用java配置。
是否可以重复使用@Component
注释而不是引入@Bean
注释?我的理解是,最终目标是在两种情况下都创建bean。
答案 0 :(得分:333)
@Component
和@Bean
做了两件截然不同的事情,不应该混淆。
@Component
(以及@Service
和@Repository
)用于使用类路径扫描自动检测和自动配置bean。注释类和bean之间存在隐式的一对一映射(即每个类一个bean)。这种方法对布线的控制非常有限,因为它纯粹是声明性的。
@Bean
用于显式声明单个bean,而不是像上面那样让Spring自动执行。它将bean的声明与类定义分离,并允许您根据自己的选择创建和配置bean。
回答你的问题...
是否可以重复使用
@Component
注释而不是引入@Bean
注释?
当然可能;但他们选择不这样做,因为两者完全不同。春天已经足够混乱,没有进一步混淆水域。
答案 1 :(得分:256)
<强> @Component 强> 优选用于元件扫描和自动布线。
什么时候应该使用 @Bean ?
有时自动配置不是一种选择。 什么时候?让我们假设您想要连接第三方库中的组件(您没有源代码,因此您无法使用@Component注释其类),因此无法自动配置。
@Bean 注释返回一个对象,spring应该在应用程序上下文中注册为bean。 方法主体承担了负责创建实例的逻辑。
答案 2 :(得分:147)
让我们考虑一下,我希望具体实现取决于某些动态状态。
private void TestGrid_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
int currentCell = TestGrid.CurrentCell.ColumnIndex;
var oldValue = TestGrid[e.ColumnIndex, e.RowIndex].Value;
var newValue = TestGrid[e.ColumnIndex, e.RowIndex].EditedFormattedValue;
/* Perform some logic here*/
}
非常适合这种情况。
@Bean
然而,使用@Bean
@Scope("prototype")
public SomeService someService() {
switch (state) {
case 1:
return new Impl1();
case 2:
return new Impl2();
case 3:
return new Impl3();
default:
return new Impl();
}
}
无法做到这一点。
答案 3 :(得分:66)
这两种方法都旨在在Spring容器中注册目标类型。
区别在于/Users/john/.ssh/config
适用于方法,而@Bean
适用于类型。
因此,当您使用@Component
注释时,您可以控制方法体中的实例创建逻辑(请参阅example above)。使用@Bean
注释,您不能。
答案 4 :(得分:46)
答案 5 :(得分:32)
@Component 这是一个通用注释,可以应用于应用程序的任何类,以使其成为Spring托管组件(简单来说,是任何Spring托管组件的通用构造型)。当通过spring的component-scan (@ ComponentScan)功能扫描类路径时,它将识别在给定包中带有 @Component 批注的类,并创建这些类的bean并在ApplicationContext中注册它们。 @Component 是一个类级别的注释,其目的是使该类成为spring托管组件和用于类路径扫描功能的自动检测bean。
如果您想进一步了解 @Component 和其他构造型注释,建议使用look at this article。
@Bean 用于在方法返回的Spring IOC容器中显式声明和注册一个Bean(作为配置Bean)。 @Bean是方法级别的注释,它在用 @Configuration 注释的类中使用。只需使用 @Bean 批注将方法返回的Bean注册为IOC容器中的spring配置Bean。 @Bean 只是方法级别的注释,不能与类和对象声明一起使用。
@Bean 注释表示方法产生了一个应由Spring容器管理的bean。
要声明一个bean,只需使用 @Bean 注释对方法进行注释。当JavaConfig遇到这样的方法时,它将执行该方法并将返回值注册为ApplicationContext中的Bean。默认情况下,bean名称将与方法名称相同。以下是@Bean方法声明的简单示例。
@Configuration
public class ApplicationConfig {
@Bean
public User adminUserProfile() {
return new User("Rami","Nassar");
}
}
在ApplicationConfig类中,您可以看到我们首先使用 @Configuration 批注通知Spring这是一个基于Java的配置文件。之后, @Bean 批注用于声明Spring bean和DI需求。 @Bean 注释等效于 标记,方法名称等效于 标记内的id属性。 我希望阅读完本文后,您对 @Bean 和 @Component 批注的实际用途和用法有了清晰的认识。
答案 6 :(得分:13)
当您使用@Component
标记时,它与使用带有vanilla bean声明方法的POJO(Plain Old Java Object)相同(使用@Bean
注释)。例如,以下方法1和2将给出相同的结果。
方法1
@Component
public class SomeClass {
private int number;
public SomeClass(Integer theNumber){
this.number = theNumber.intValue();
}
public int getNumber(){
return this.number;
}
}
使用bean来获取&#39; theNumber&#39;:
@Bean
Integer theNumber(){
return new Integer(3456);
}
方法2
//Note: no @Component tag
public class SomeClass {
private int number;
public SomeClass(Integer theNumber){
this.number = theNumber.intValue();
}
public int getNumber(){
return this.number;
}
}
使用两者的bean:
@Bean
Integer theNumber(){
return new Integer(3456);
}
@Bean
SomeClass someClass(Integer theNumber){
return new SomeClass(theNumber);
}
方法2允许您将bean声明保持在一起,它更灵活等等。您甚至可能想要添加另一个非vanilla SomeClass bean,如下所示:
@Bean
SomeClass strawberryClass(){
return new SomeClass(new Integer(1));
}
答案 7 :(得分:8)
答案 8 :(得分:4)
- @Controller public class LoginController { --code-- } - @Configuration public class AppConfig { @Bean public SessionFactory sessionFactory() {--code-- }
答案 9 :(得分:4)
您有两种生成bean的方法。
一种是用注解@Component
创建一个类。
另一种是创建一个方法并用@Bean
对其进行注释。对于那些包含方法@Bean
的类,应使用@Configuration
进行注释。
运行spring项目后,带有@ComponentScan
批注的类将扫描带有@Component
的每个类,并将该类的实例还原到Ioc容器。 @ComponentScan
要做的另一件事是运行带有@Bean
的方法,并将返回对象作为bean恢复到Ioc容器。
因此,当需要根据当前状态决定要创建哪种类型的bean时,需要使用@Bean
。您可以编写逻辑并返回所需的对象。
值得一提的是,@Bean
方法的名称是bean的默认名称。
答案 10 :(得分:2)
@Bean的创建是为了避免在编译时将Spring和您的业务规则耦合在一起。这意味着您可以在其他框架(如PlayFramework或JEE)中重用业务规则。
此外,您可以完全控制如何创建bean,而这在默认的Spring实例中还不够。
我写了一篇关于它的文章。
https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/
答案 11 :(得分:2)
您可以使用@Bean
使现有的第三方类可用于您的Spring框架应用程序上下文。
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
通过使用@Bean
批注,您可以将第三方类(它可能没有@Component
,并且可能不使用Spring)包装为Spring bean。然后,使用@Bean
包装它之后,它就作为一个单例对象,可以在您的Spring框架应用程序上下文中使用。现在,您可以使用依赖项注入和@Autowired
在应用程序中轻松共享/重用此bean。
因此,请注意@Bean
注释是第三方类的包装器/适配器。您希望使第三方类可用于您的Spring框架应用程序上下文。
通过在上面的代码中使用@Bean
,我明确声明了一个bean,因为在方法内部,我使用new
关键字明确创建了对象。我还手动调用给定类的setter方法。因此,我可以更改前缀字段的值。因此,此手动工作称为显式创建。如果我将@Component
用于同一类,则在Spring容器中注册的Bean将具有前缀字段的默认值。
另一方面,当我们用@Component
注释一个类时,不需要我们手动使用new
关键字。它由Spring自动处理。
答案 12 :(得分:1)
我看到了很多答案,几乎所有提到的@Component都是用于自动装配的,其中扫描了组件,而@Bean精确地声明该bean的使用方式不同。让我展示一下它的不同之处。
首先是方法级别的注释。 其次,通常使用Java代码配置bean(如果不使用xml配置),然后使用 ApplicationContext的getBean方法。 像
@Configuration
class MyConfiguration{
@Bean
public User getUser(){
return new User();
}
}
class User{
}
//Getting Bean
User user = applicationContext.getBean("getUser");
这是注释bean而不是专用bean的通用方法。 类级别的注释,用于避免通过Java或xml配置进行的所有配置工作。
我们得到这样的东西。
@Component
class User {
}
//to get Bean
@Autowired
User user;
就是这样。引入它是为了避免实例化和使用该bean的所有配置步骤。
答案 13 :(得分:1)
1。关于@Component
@Component功能类似于@Configuration。
它们都表明带注释的类具有一个或多个bean,需要注册到Spring-IOC-Container
。
@Component注释的类,我们称之为Component of Spring
。这个概念包含几个bean。
Spring需要对Component class
进行自动扫描,以注册component class
的那些bean。
2。关于@Bean
@Bean用于注释component-class
的方法(如上所述)。它指示通过带注释的方法撤消的实例需要注册到Spring-IOC-Container
。
3。结论
两者之间的区别相对明显,它们用在different circumstances
中。
常规用法是:
// @Configuration is implemented by @Component
@Configuration
public ComponentClass {
@Bean
public FirstBean FirstBeanMethod() {
return new FirstBean();
}
@Bean
public SecondBean SecondBeanMethod() {
return new SecondBean();
}
}
答案 14 :(得分:1)
以上答案中的附加点
假设我们有一个模块,该模块可以在多个应用程序中共享,并且其中包含一些服务。并非每个应用程序都需要全部。
如果在这些服务类上使用@Component并在应用程序中扫描组件,则
我们可能最终检测到的豆超过了必要
在这种情况下,您要么必须调整组件扫描的过滤,要么提供即使未使用的bean也可以运行的配置。否则,应用程序上下文将无法启动。
在这种情况下,最好使用@Bean批注并仅实例化那些bean,
每个应用中分别需要的
因此,从本质上讲,可以使用@Bean将第三方类添加到上下文中。还有@Component(如果它位于您的单个应用程序中)。
答案 15 :(得分:0)
@Component
的意思是“导入”。
@Bean
的意思是“导出”。