use*_*576 387 java spring annotations autowired
我知道@Component在Spring 2.5中引入了注释,以便通过使用类路径扫描来消除xml bean的定义.
@Bean是在3.0版本中引入的,可以用来@Configuration完全摆脱xml文件并使用java配置.
是否可以重复使用@Component注释而不是引入@Bean注释?我的理解是,最终目标是在两种情况下都创建bean.
ska*_*man 388
@Component和@Bean做两个完全不同的事情,不应该混为一谈.
@Component(和@Service和@Repository)用于自动检测和使用类路径扫描自动配置豆.注释类和bean之间存在隐式的一对一映射(即每个类一个bean).这种方法对布线的控制非常有限,因为它纯粹是声明性的.
@Bean用于显式声明单个bean,而不是让Spring像上面那样自动执行它.它将bean的声明与类定义分离,并允许您根据自己的选择创建和配置bean.
回答你的问题......
是否可以重复使用
@Component注释而不是引入@Bean注释?
当然可能; 但他们选择不这样做,因为两者完全不同.春天已经足够混乱,没有进一步混淆水域.
Mag*_*GGG 341
@Component优先 用于元件扫描和自动布线.
什么时候应该使用@Bean?
有时自动配置不是一种选择.什么时候?让我们假设您想要连接来自第三方库的组件(您没有源代码,因此您无法使用@Component注释其类),因此无法进行自动配置.
所述@Bean注释返回一个对象该弹簧应在应用程序上下文豆注册.方法的主体承担负责创建实例的逻辑.
out*_*dev 159
让我们考虑一下我需要具体的实现,具体取决于一些动态状态.
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
然而,没有办法做到这一点@Component.
小智 73
Som*_*Guy 15
当您使用@Component标记时,它与具有vanilla bean声明方法(带注释@Bean)的POJO(Plain Old Java Object)相同.例如,以下方法1和2将给出相同的结果.
方法1
@Component
public class SomeClass {
private int number;
public SomeClass(Integer theNumber){
this.number = theNumber.intValue();
}
public int getNumber(){
return this.number;
}
}
Run Code Online (Sandbox Code Playgroud)
用'theNumber'的豆子:
@Bean
Integer theNumber(){
return new Integer(3456);
}
Run Code Online (Sandbox Code Playgroud)
方法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;
}
}
Run Code Online (Sandbox Code Playgroud)
与两者的豆:
@Bean
Integer theNumber(){
return new Integer(3456);
}
@Bean
SomeClass someClass(Integer theNumber){
return new SomeClass(theNumber);
}
Run Code Online (Sandbox Code Playgroud)
方法2允许您将bean声明保持在一起,它更灵活等等.您甚至可能希望添加另一个非vanilla SomeClass bean,如下所示:
@Bean
SomeClass strawberryClass(){
return new SomeClass(new Integer(1));
}
Run Code Online (Sandbox Code Playgroud)
Par*_*tho 13
Spring支持@Component、@Service、@Repository等多种类型注解。所有这些都可以在 org.springframework.stereotype 包下找到。
@Bean可以在org.springframework.context.annotation包下找到。
当我们应用程序中的类使用上述任何注释进行注释时,然后在项目启动期间 spring 扫描(使用 @ComponentScan)每个类并将类的实例注入 IOC 容器。@ComponentScan 要做的另一件事是运行带有 @Bean 的方法,并将返回对象作为 bean 恢复到 Ioc 容器。
如果我们用 @Component 或其他 Stereotype 注释之一标记一个类,这些类将使用类路径扫描自动检测。只要这些类位于我们的基础包下或者 Spring 知道要扫描另一个包,就会为每个类创建一个新的 bean。
package com.beanvscomponent.controller;
import org.springframework.stereotype.Controller;
@Controller
public class HomeController {
public String home(){
return "Hello, World!";
}
}
Run Code Online (Sandbox Code Playgroud)
带注释的类和 bean 之间存在隐式的一对一映射(即每个类一个 bean)。这种方法的接线控制非常有限,因为它纯粹是声明性的。还需要注意的是,构造型注释是类级别注释。
@Bean 用于显式声明单个 bean,而不是像我们使用 @Controller 那样让 Spring 自动执行此操作。它将 bean 的声明与类定义分离,并允许您准确地按照您选择的方式创建和配置 bean。使用@Bean,您不会将此注释放置在类级别。如果您尝试这样做,您将收到无效类型错误。@Bean 文档将其定义为:
Indicates that a method produces a bean to be managed by the Spring container.
Run Code Online (Sandbox Code Playgroud)
通常,@Bean 方法在 @Configuration 类中声明。我们有一个用户类,需要实例化,然后使用该实例创建一个 bean。这就是我之前所说的,我们对 bean 的定义方式有更多的控制权。
package com.beanvscomponent;
public class User {
private String first;
private String last;
public User(String first, String last) {
this.first = first;
this.last = last;
}
}
Run Code Online (Sandbox Code Playgroud)
正如我之前提到的,@Bean 方法应该在 @Configuration 类中声明。
package com.beanvscomponent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ApplicationConfig {
@Bean
public User superUser() {
return new User("Partho","Bappy");
}
}
Run Code Online (Sandbox Code Playgroud)
该方法的名称实际上就是我们 bean 的名称。如果我们在执行器中拉出 /beans 端点,我们可以看到定义的 bean。
{
"beans": "superUser",
"aliases": [],
"scope": "singleton",
"type": "com.beanvscomponent.User",
"resource": "class path resource
[com/beanvscomponent/ApplicationConfig.class]",
"dependencies": []
}
Run Code Online (Sandbox Code Playgroud)
我希望这能够澄清一些关于何时使用 @Component 以及何时使用 @Bean 的问题。这可能有点令人困惑,但是当您开始编写更多应用程序时,它会变得非常自然。
xpi*_*eer 12
我看到了很多答案,几乎所有提到的@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");
Run Code Online (Sandbox Code Playgroud)
这是注释bean而不是专用bean的通用方法。类级别的注释,用于避免通过Java或xml配置进行的所有配置工作。
我们得到这样的东西。
@Component
class User {
}
//to get Bean
@Autowired
User user;
Run Code Online (Sandbox Code Playgroud)
而已 。引入它是为了避免实例化和使用该bean的所有配置步骤。
Aza*_*rEJ 11
Bean和组件的区别:
elv*_*vis 10
您可以@Bean用来使现有的第三方类对您的Spring框架应用程序上下文可用。
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/view/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
Run Code Online (Sandbox Code Playgroud)
通过使用@Bean注释,您可以将第三方类(它可能没有@Component,也可能不使用Spring)包装为Spring bean。然后,使用对其进行包装后@Bean,它就作为一个单例对象,可以在您的Spring框架应用程序上下文中使用。现在,您可以使用依赖项注入和轻松在应用程序中共享/重用此bean @Autowired。
因此,请注意@Bean注释是第三方类的包装器/适配器。您想使第三方类可用于您的Spring框架应用程序上下文。
通过@Bean在上面的代码中使用,我明确声明了一个bean,因为在方法内部,我使用new关键字明确创建了对象。我还手动调用给定类的setter方法。因此,我可以更改前缀字段的值。因此,此手动工作称为显式创建。如果我@Component对同一类使用,则在Spring容器中注册的Bean将具有前缀字段的默认值。
另一方面,当我们使用注释类时@Component,无需手动使用new关键字。它由Spring自动处理。
您有两种生成bean的方法。一种是创建带有注释的类@Component。另一种是创建一个方法并使用进行注释@Bean。对于那些包含方法的类,@Bean应使用注释。@Configuration
一旦运行spring项目,带有@ComponentScan注释的类将扫描其上的每个类@Component,并将该类的实例还原到Ioc容器。要做的另一件事@ComponentScan是在其@Bean上运行方法,并将返回对象作为Bean恢复到Ioc容器。因此,当您需要根据当前状态决定要创建哪种类型的bean时,需要使用@Bean。您可以编写逻辑并返回所需的对象。另一件事值得一提的是with的方法@Bean名称是bean的默认名称。
小智 6
@Bean 的创建是为了避免在编译时耦合 Spring 和您的业务规则。这意味着您可以在 PlayFramework 或 JEE 等其他框架中重用您的业务规则。
此外,您可以完全控制如何创建 bean,而默认的 Spring 实例是不够的。
我写了一篇文章谈论它。
https://coderstower.com/2019/04/23/factory-methods-decoupling-ioc-container-abstraction/
-@Controller
公共类LoginController
{--code--}
-@配置
公共类AppConfig {
@豆
公共SessionFactory sessionFactory()
{--code--}
上述答案的补充要点
\n\n让\xe2\x80\x99s 说我们有一个在多个应用程序中共享的模块,并且它包含一些服务。并非每个应用程序都需要所有内容。
\n\n如果在这些服务类上使用@Component并且在应用程序中扫描组件,
\n\n\n\n\n我们最终可能会检测到不必要的豆子
\n
在这种情况下,您要么必须调整组件扫描的过滤,要么提供甚至未使用的 bean 也可以运行的配置。否则,应用程序上下文将无法启动\xe2\x80\x99。
\n\n在这种情况下,最好使用 @Bean 注释并仅实例化这些 bean,
\n\n\n\n\n每个应用程序都需要单独的
\n
因此,本质上,使用 @Bean 将第三方类添加到上下文中。如果它就在您的单个应用程序中,则@Component 。
\n| 归档时间: |
|
| 查看次数: |
209284 次 |
| 最近记录: |