了解spring @Configuration类 [英] Understanding spring @Configuration class
问题描述
按照问题了解Spring @Autowired用法我想为弹簧接线的其他选择创建一个完整的知识库,@Configuration
类.
Following the question Understanding Spring @Autowired usage I wanted to create a complete knowledge base for the other option of spring wiring, the @Configuration
class.
假设我有一个看起来像这样的spring XML文件:
Let's assume I have a spring XML file that looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="another-application-context.xml"/>
<bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
<constructor-arg value="${some.interesting.property}" />
</bean>
<bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
<constructor-arg ref="someBean"/>
<constructor-arg ref="beanFromSomewhereElse"/>
</bean>
</beans>
如何使用@Configuration
代替?对代码本身有影响吗?
How can I use @Configuration
instead? Does it have any affect on the code itself?
推荐答案
将XML迁移到@Configuration
可以通过几个步骤将xml迁移到@Configuration
:
-
创建一个带有
@Configuration
注释的类:
@Configuration
public class MyApplicationContext {
}
为每个<bean>
标签创建一个用@Bean
注释的方法:
For each <bean>
tag create a method annotated with @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
:
In order to import beanFromSomewhereElse
we need to import it's definition. It can be defined in an XML and the we'll use @ImportResource
:
@ImportResource("another-application-context.xml")
@Configuration
public class MyApplicationContext {
...
}
如果Bean是在另一个@Configuration
类中定义的,则可以使用@Import
批注:
If the bean is defined in another @Configuration
class we can use the @Import
annotation:
@Import(OtherConfiguration.class)
@Configuration
public class MyApplicationContext {
...
}
导入其他XML或@Configuration
类之后,我们可以通过在@Configuration
类中声明一个私有成员来使用它们在上下文中声明的bean,如下所示:
After we imported other XMLs or @Configuration
classes, we can use the beans they declare in our context by declaring a private member to the @Configuration
class as follows:
@Autowired
@Qualifier(value = "beanFromSomewhereElse")
private final StrangeBean beanFromSomewhereElse;
或直接使用它作为使用@Qualifier
定义依赖于此beanFromSomewhereElse
的bean的方法中的参数,如下所示:
Or use it directly as parameter in the method which defines the bean that depends on this beanFromSomewhereElse
using @Qualifier
as follows:
@Bean(name = "anotherBean")
public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) {
return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse);
}
导入属性与从另一个xml或@Configuration
类导入bean非常相似.代替使用@Qualifier
,我们将使用具有以下属性的@Value
:
Importing properties is very similar to importing bean from another xml or @Configuration
class. Instead of using @Qualifier
we'll use @Value
with properties as follows:
@Autowired
@Value("${some.interesting.property}")
private final String someInterestingProperty;
这也可以与 SpEL 表达式一起使用.
This can be used with SpEL expressions as well.
为了允许spring将此类视为bean容器,我们需要通过将以下标记放在上下文中来在主xml中对其进行标记:
In order to allow spring to treat such classes as beans containers we need to mark this in our main xml by putting this tag in the context:
<context:annotation-config/>
现在,您可以导入与创建简单bean完全相同的@Configuration
类:
You can now import @Configuration
classes exactly the same as you would create a simple bean:
<bean class="some.package.MyApplicationContext"/>
有一些方法可以完全避免使用Spring XML,但是它们不在此答案的范围之内.您可以在我的博客帖子,我以此为依据.
There are ways to avoid spring XMLs altogether but they are not in the scope of this answer. You can find out one of these options in my blog post on which I'm basing my answer.
使用此方法的优缺点
基本上,由于一些优势,我发现这种声明bean的方法比使用XML更舒适:
The advantages and disadvantages of using this method
Basically I find this method of declaring beans much more comfortable than using XMLs due to a few advantages I see:
- 错别字-
@Configuration
类已编译,错别字只是不允许编译 - 快速失败(编译时)-如果您忘记注入Bean,则会在编译时失败,而不是像XML那样在运行时失败
- 更容易在IDE中导航-在bean的构造函数之间理解依赖关系树.
- 可以轻松调试配置启动
- Typos -
@Configuration
classes are compiled and typos just won't allow compilations - Fail fast (compile time) - If you forget to inject a bean you'll fail on compile time and not on run-time as with XMLs
- Easier to navigate in IDE - between constructors of beans to understand the dependency tree.
- Possible to easily debug configuration startup
我所看到的缺点并不多,但我可以想到一些缺点:
The disadvantages are not many as I see them but there are a few which I could think of:
- 滥用-代码比XML更容易滥用
- 使用XML,您可以基于在编译时不可用但在运行时提供的类定义依赖关系.使用
@Configuration
类,必须在编译时提供可用的类.通常这不是问题,但是在某些情况下可能是这样.
- Abuse - Code is easier to abuse than XMLs
- With XMLs you can define dependencies based on classes that are not available during compile time but are provided during run-time. With
@Configuration
classes you must have the classes available at compile time. Usually that's not an issue, but there are cases it may be.
底线:在您的应用程序上下文中结合使用XML,@Configuration
和注释完全可以. Spring并不关心使用bean声明的方法.
Bottom line: It is perfectly fine to combine XMLs, @Configuration
and annotations in your application context. Spring doesn't care about the method a bean was declared with.
这篇关于了解spring @Configuration类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!