Java @Bean和@Autowired之间的区别
为什么我不能在这种情况下使用Java @Bean和@Autowired之间的区别,java,spring,dependency-injection,Java,Spring,Dependency Injection,为什么我不能在这种情况下使用@Autowired @SpringBootApplication public class Application { @Autowired BookingService bookingService; public static void main(String[] args) { bookingService.book("Alice", "Bob", "Carol"); } } 但是可以使用@Bean @Sp
@Autowired
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
但是可以使用@Bean
@SpringBootApplication
public class Application {
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
BookingService bookingService = ctx.getBean(BookingService.class);
bookingService.book("Alice", "Bob", "Carol");
}
}
生成BookingService
的两种方法不是一回事吗
@Bean
BookingService bookingService() {
return new BookingService();
}
注释@Bean
仅将服务注册为spring应用程序上下文中的Bean(对象类型)。简单地说,这只是注册而已
@Autowired
BookingService bookingService;
用@Autowired
注释变量会从Spring应用程序上下文中注入BookingService
bean(即对象)
(即)带有@bean
注释的注册bean将被注入带有@Autowired
注释的变量
希望这能消除你的疑虑
@Bean
和@Autowired
做两件截然不同的事情。这里的其他答案解释得更详细一些,但更简单:
告诉Spring“这是这个类的一个实例,请保留它,当我问起的时候把它还给我。”@Bean
说“请给我一个这个类的实例,例如,一个我先前用@Autowired
注释创建的实例”@Bean
BookingService
实例,但您从未创建过一个实例,因此Spring没有提供任何东西。在第二个示例中,您正在创建一个新的BookingService
实例,向Spring介绍它,然后在main()
方法中要求返回它
如果需要,可以从第二个main()
方法中删除另外两行,并将两个示例组合在一起,如下所示:
@SpringBootApplication
public class Application {
@Autowired
BookingService bookingService;
@Bean
BookingService bookingService() {
return new BookingService();
}
public static void main(String[] args) {
bookingService.book("Alice", "Bob", "Carol");
}
}
在本例中,@Bean
注释为Spring提供了BookingService
,而@Autowired
利用了它
这是一个稍微没有意义的例子,因为您在同一个类中使用它,但是如果您在一个类中定义了
@Bean
,而在另一个类中定义了@Autowired
。由@daveydave提供的很好的答案,那么它会变得很有用
在示例中,而不是
@Bean
BookingService bookingService() {
return new BookingService();
}
您可以在BookingService类上使用@Service annotation这里有一篇关于
@Autowired
注释的好文章:
通过在config类上定义@ComponentScan(“namespace.with.your.components.for.inject”)
,自动连线的@Autowired
注释可以实例化可注入项
@Configuration
@ComponentScan("com.baeldung.autowire.sample")
public class AppConfig {}
所有组件必须用
@Component
注释进行标记。它取代了@Bean
注释。@Bean只是用于元数据定义来创建Bean(相当于标记)@Autowired是将依赖性注入到bean中(相当于ref-XML标记/属性)。@Autowired和@bean都是注册Springbean的方法
与投票率最高的答案所宣称的相反,它们并不是两件完全不同的事情@Bean和@Autowired在大多数情况下是可互换的。(更多信息请参见下文)
假设有一个@Bean方法返回一个Car实例。您可以直接去掉该bean方法,在Car类上添加@Component,然后自动连接它
反之亦然。无论您使用@Autowired实例化了什么类,您都可以在方法上使用@Bean在带有@Configuration注释的类中实例化它
不同之处在于,如果您使用@Bean实例化一个类,那么您可以更好地控制初始化。例如,如果您正在实例化Resilience4J断路器类,如果您在@Bean方法中执行此操作,那么您可以选择使用如下代码设置所有配置
@Bean
public CircuitBreaker fooCircuitBreaker() {
CircuitBreakerConfig.Builder builder = CircuitBreakerConfig.custom().
slidingWindowSize(xxx).
failureRateThreshold(xxx).
waitDurationInOpenState(xxx)).
ignoreException(e -> {
if (e instanceof HttpStatusCodeException) {
HttpStatusCodeException httpStatusCodeException = (HttpStatusCodeException) e;
if (httpStatusCodeException.getStatusCode().is4xxClientError()) {
return true;
}
}
return false;
});
circuitBreakerRegistry.addConfiguration(xxx, builder.build());
return circuitBreakerRegistry.circuitBreaker(xxx, xxx);
}
在大多数情况下,@Autowired(和@Component)工作得非常好。
@豆子只是偶尔需要。通常是因为您无权更改类以向其添加@Component注释,或者因为您需要对类的初始化有更多的控制。Bean注释用于在spring上下文中注册Bean,而Autowried注释用于从spring应用程序内容获取Bean并对其进行连接作为另一个对象的依赖项,您也应该提供BookingService类。因为如果使用组件对其进行注释,那么您的第一个类也会像第二个类一样工作。但是,如果我将BookingService与@AutowiredNow一起注入BookingService,则我无法使用BookingService的功能。我知道这是因为在main()中,我出现了错误“将book()的修饰符更改为static”,我可以在其他函数中使用BookingService的对象,但我不能why@zhuochenshen我不知道你们班里有什么,也不知道现在的问题。我只回答了你的“不同”问题。关于下一个问题,您可以发布另一个问题。
即,使用@bean注册的bean将被注入到使用@Autowired注释的变量。
这一行是这两个注释的精髓所在。不知怎的,这个答案对我来说似乎只是部分正确。Autowired还可以调用带有@Components注释的对象。此外,Autowired不仅可以用于对象,还可以用于方法。@PowerFlower,绝对正确,我在这里的目的是解释问题上下文中的差异。当然,这两种注释都要复杂得多,但我试图对这个具体的例子给出一个简单、高层次的解释。这个答案是错误的。不知道为什么会有这么多人投票。Bean和autowire在大多数情况下是可互换的。检查我下面的答案。对不起,我认为你错了。也许你误解了我所说的“非常不同”的意思,也许“同一枚硬币的两面”更合适。但毫无疑问,它们是不能互换的@Bean
和@Component
可以互换,因为它们都注册Bean,但是@Autowired
不注册Bean。如果您有一个可以互换使用它们的示例,那么可以将您的答案编辑为incl