理解spring @Configuration类
理解spring @Configuration类
在理解Spring @Autowired用法的问题之后,我想为另一种Spring装配选项创建一个完整的知识库,即@Configuration
类。
假设我有一个这样的Spring XML文件:
我如何使用@Configuration
? 它对代码本身有任何影响吗?
将XML迁移到@Configuration
可以通过以下几个步骤将XML迁移到@Configuration
:
-
创建一个带有
@Configuration
注解的类:@Configuration public class MyApplicationContext { }
-
对于每个
标记,创建一个使用@Bean
注解的方法:@Configuration public class MyApplicationContext { @Bean(name = "someBean") public SomeClass getSomeClass() { return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty } @Bean(name = "anotherBean") public AnotherClass getAnotherClass() { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse } }
-
为了导入
beanFromSomewhereElse
,我们需要导入它的定义。它可以在XML中定义,然后我们将使用@ImportResource
:@ImportResource("another-application-context.xml") @Configuration public class MyApplicationContext { ... }
如果bean在另一个
@Configuration
类中定义,我们可以使用@Import
注解:@Import(OtherConfiguration.class) @Configuration public class MyApplicationContext { ... }
-
在导入其他XML或
@Configuration
类之后,我们可以通过下面的方式在我们的上下文中声明一个私有成员来使用它们声明的bean:@Autowired @Qualifier(value = "beanFromSomewhereElse") private final StrangeBean beanFromSomewhereElse;
或直接将其用作依赖于此
beanFromSomewhereElse
的bean的定义方法中的参数,如下所示使用@Qualifier
:@Bean(name = "anotherBean") public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) { return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); }
-
导入属性与从其他xml或
@Configuration
类导入bean非常相似。我们将使用属性以如下方式使用@Value
而不是使用@Qualifier
:@Autowired @Value("${some.interesting.property}") private final String someInterestingProperty;
这也可以与SpEL表达式一起使用。
-
为了让Spring将这些类视为bean容器,我们需要在主XML中使用此标记将其标记:
现在你可以像创建简单的bean一样导入
@Configuration
类:有方法可以完全避免使用Spring XMLs,但这不在本答案的范围之内。您可以在我的博客文章中找到其中一个选项,我也是根据这个答案写的。
使用此方法的优缺点
基本上,由于我看到了以下几点优势,我觉得这种声明bean的方法比使用XMLs更加舒适:
- 拼写错误 -
@Configuration
类是编译的,拼写错误会导致编译无法通过。 - 快速失败(编译时) - 如果您忘记注入一个bean,则会在编译时失败,而不是像XMLs一样在运行时失败。
- 易于在IDE中导航 - 可以在bean的构造函数之间导航,以了解依赖关系树。
- 可能轻松调试配置启动
我认为缺点并不是很多,但有一些,我可以想到以下几个:
- 滥用 - 代码比XMLs更容易被滥用。
- 使用XMLs,您可以基于在编译时不可用但在运行时提供的类定义依赖项。使用
@Configuration
类时,必须在编译时拥有这些类。通常,这不是问题,但也有可能。
底线:在应用程序上下文中,将XMLs、@Configuration
和注释组合使用是完全可以的。Spring不关心bean被声明的方法。