在某些情况下,我有一个无法用@Configuration
注释的Spring配置类。一开始我以为它无法工作,因为Spring配置必须带有@Configuration
注释。但是,在进行了一些测试之后,我才意识到@Configuration
不是强制性的。
例如,这是一个不含@Configuration
的配置Java类:
public class NotAnnotatedConfiguration {
@Bean
public DemoService demoService() {
return new DemoService();
}
}
我已尝试在以下测试中加载此配置:
@ContextConfiguration(classes = NotAnnotatedConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class NotAnnotatedConfigurationTest {
@Autowired DemoService demoService;
@Test
public void load() {
assertNotNull(this.demoService);
}
}
它有效!在真实的应用程序中,不仅在测试中,我得到相同的结果。
根据我的测试,我认为@Configuration
仅在您希望Spring扫描类时才是必需的,否则您可以给Spring提供未注释的配置,它将加载并扫描所有定义的bean在里面。但是,AnnotationConfigApplicationContext
的javadoc对我来说似乎不太清楚(可能我误解了):
/**
* Create a new AnnotationConfigApplicationContext, deriving bean definitions
* from the given annotated classes and automatically refreshing the context.
* @param annotatedClasses one or more annotated classes,
* e.g. {@link Configuration @Configuration} classes
*/
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
我用测试创建了一个github存储库,以分享我的结论:https://github.com/itelleria/configuration-annotation
问题是,尽管我进行了测试,但是否可以在Spring中不使用@Configuration
注释Java配置类?
先谢谢了。
答案 0 :(得分:1)
我认为您是正确的,Spring将加载config类并创建实例,但不会将实例视为Bean。含义:使用DemoService
的其他服务将为每种用法创建多个实例,而不是作为一个单独的实例创建,这是作为bean创建时的默认范围。
public class DemoServiceUsage {
DemoService demoService;
public DemoServiceUsage(DemoService demoService) {
this.demoService = demoService;
}
}
public class NotAnnotatedConfiguration {
@Bean
public DemoService demoService() {
DemoService demoService = new DemoService();
System.out.println("demoService " + demoService.hashCode());
return demoService;
}
@Bean
public DemoServiceUsage demoServiceUsage1() {
return new DemoServiceUsage(demoService());
}
@Bean
public DemoServiceUsage demoServiceUsage2() {
return new DemoServiceUsage(demoService());
}
}
@Configuration
@Import({
NotAnnotatedConfiguration.class
})
public class ApplicationConfig {
}
@ContextConfiguration(classes = ApplicationConfiguration.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class NotAnnotatedConfigurationTest {
@Autowired
DemoServiceUsage demoServiceUsage1;
@Autowired
DemoServiceUsage demoServiceUsage2;
@Test
public void load() {
assertNotNull(this.demoServiceUsage1);
assertNotNull(this.demoServiceUsage2);
}
}
在这里,您将看到获得带有不同hashCode的多个demoService输出。如果demoService
是一个bean,我们应该只看到一个实例,因为它应该具有单例作用域。
答案 1 :(得分:0)
您的案例可能不需要Configuration,但是首先您可以遵循将类注释为设计的惯例,并且正如您所提到的,当有人进行组件扫描时会出现问题,因为您将需要添加@Component
或其他带有元注释的内容:
@Configuration使用@Component进行元注释,因此@Configuration类是组件扫描的候选对象
还可以在“配置”中包括组件扫描:
@Configuration类不仅可以使用组件扫描来引导,还可以自己使用@ComponentScan注释来配置组件扫描:
@Configuration @ComponentScan("com.acme.app.services") public class AppConfig { // various @Bean definitions ... }