Java配置允许我们在配置文件中管理bean创建。带注释的@Component,与组件扫描一起使用的@Service类也是如此。但是,我担心同时使用这两种机制。
在同一个项目中是否应避免Java配置和带注释的组件扫描?我问,因为在以下情况中结果不清楚:
@Configuration
public class MyConfig {
@Bean
public Foo foo() {
return new Foo(500);
}
}
...
@Component
public class Foo {
private int value;
public Foo() {
}
public Foo(int value) {
this.value = value;
}
}
...
public class Consumer {
@Autowired
Foo foo;
...
}
那么,在上述情况下,Consumer会获得一个500值或0值的Foo实例吗?我在本地进行了测试,看起来Java配置的Foo(值为500)是一致的。但是,我担心我的测试不够透彻,无法确定。
真正的答案是什么?在相同类型的@Component bean上使用Java config 和组件扫描似乎是一件坏事。
答案 0 :(得分:1)
通常,在同一应用程序上下文中组件扫描和显式bean定义没有任何问题。我倾向于尽可能使用组件扫描,并使用@Bean
方法创建需要更多设置的少数bean。
当您明确创建其类型的bean时,在组件扫描中包含类没有任何好处。组件扫描可以轻松地针对某些类和包。如果你相应地设计你的包,你可以只扫描没有“特殊”bean类的包(或者在扫描时使用更高级的过滤器)。
在这种情况下,我没有找到关于bean定义优先级的任何明确信息。通常会有一个确定性且相当稳定的顺序来处理这些顺序,但是如果没有记录它可能可能在未来的某个Spring版本中发生变化。
答案 1 :(得分:1)
我认为您的担忧更像是由以下用例引起的:
您有一个自定义的spring-starter-library,它具有自己的<div class="hero-container-2">
<span id="contactus"></span>
<p><span id="contactus">Itching to ask us a question about the club? Want to pick our brains about training, competing or joining? (We usually react quickly, but it might take us a handful of days to reply).</span></p>
<div class="buttom">
<span id="contactus">Contact Us</span>
</div>
</div>
类和@Configuration
定义,但如果此库中有@Bean
,则需要显式{{ 1}}这些包来自您的服务,因为默认的@Component/@Service
(请参见@ComponentScan
)将从主类执行组件扫描,直到您应用的所有子包,但外部包图书馆。为此,您只需要在外部库中拥有@ComponentScan
定义,并通过应用主类上使用的@SpringBootApplication
注释(使用@Bean
或使用{ {1}},以防您始终需要使用/注入外部配置。
当然,您可以在该库中使用@EnableSomething
,但是在某些情况下显式使用@Import(YourConfigurationAnnotatedClass.class)
注释可能会导致意外行为,因此我建议避免这种情况。
因此,要回答您的问题->仅当它们在您的应用程序内部时,您才可以使用两种方法来定义bean,但是应在应用程序外部(例如库)中使用spring.factories
来明确定义bean定义。 @Components
类。
答案 2 :(得分:0)
在同一个项目中进行Java配置和带批注的组件扫描是完全有效的,因为它们服务于不同的目的。
@Component
(@Service,@Repository
等)用于自动检测和自动配置bean。
@Bean
注释用于显式声明单个bean,而不是让Spring自动执行它。
您可以使用@Bean
执行以下操作。但是,@Component
@Bean
public MyService myService(boolean someCondition) {
if(someCondition) {
return new MyServiceImpl1();
}else{
return new MyServiceImpl2();
}
}
还没有真正遇到需要同一类型的bean上的Java配置和组件扫描的情况。
要声明bean,只需使用@Bean批注注释方法即可。 当JavaConfig遇到这样的方法时,它将执行该方法 并将返回值注册为BeanFactory中的bean。通过 默认情况下,bean名称将与方法名称
相同
所以,按照这个,它返回正确的Foo(值为500)。