spring - @Configuration 是强制性的吗?
问题描述
在某些情况下,我有一个不能用@Configuration
. 一开始我以为它不能工作,因为Spring配置必须有@Configuration
注解。但是,在做了一些测试之后,我才意识到@Configuration
这不是强制性的。
例如,这是一个没有配置的 Java 类@Configuration
:
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
问题是,尽管进行了我的测试,是否允许@Configuration
在 Spring 中不使用 java 配置类进行注释?
提前致谢。
解决方案
我认为你是对的,Spring 将加载配置类并创建实例,但不会将实例视为 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,我们应该只看到一个实例,因为它应该有一个单例范围。
推荐阅读
- c# - Asp.Net Core 2.0 Cookie 身份验证提前过期
- javascript - fetch/promises - ASPX 方法返回序列化 DataTable (Newtonsoft) - 返回 Json 对象数组
- sql-server - 为什么django迁移使用MSsql提示成功,但创建表失败?
- python - 为什么在字典中使用 lambda 时 Python 中的 min() 会返回键?
- objective-c - Objc 类无法识别 Swift 类
- javascript - 在 for 循环中等待响应
- c# - 当观察到的变量位于 MainWindow.cs 中时,数据绑定无法正常工作
- python - Python - gphoto2:如何捕捉佳能 5D Mark IV 的图像
- dart - 颤振检查cpu使用情况
- javascript - ajax多文件上传卡在laravel中的请求