将Spring XML文件转换为Spring @Configuration类
下面的问题了解Spring @Autowired的用法,我想创build一个完整的知识库,用于弹簧布线的另一个选项@Configuration
类。
假设我有一个spring的XML文件,如下所示:
<?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
? 它对代码本身有什么影响吗?
(免责声明 – 这个答案是基于我的博客文章 )
将XML迁移到@Configuration
可以通过几个步骤将xml迁移到@Configuration
:
-
创build一个
@Configuration
注释类:@Configuration public class MyApplicationContext { }
-
对于每个
<bean>
标签,创build一个用@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,方法是将私有成员声明为@Configuration
类,如下所示:@Autowired @Qualifier(value = "beanFromSomewhereElse") private final StrangeBean beanFromSomewhereElse;
或者在使用
@Qualifier
定义依赖于这个beanFromSomewhereElse
的bean的方法中直接用它作为参数,如下所示:@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;
这也可以用于SpELexpression式。
-
为了让spring能够像bean容器一样处理类,我们需要在上下文中放置这个标记来在我们的主要xml中标记这个:
<context:annotation-config/>
你现在可以像创build一个简单的bean一样导入
@Configuration
类:<bean class="some.package.MyApplicationContext"/>
有许多方法可以完全避免使用Spring XML,但它们不在本答案的范围之内。 你可以在我的博客文章中find其中的一个选项,我正在根据我的答案。
使用这种方法的优点和缺点
基本上我发现这种声明bean的方法比使用XML更舒服,因为我看到了一些优点:
- 错别字 –
@Configuration
类被编译和错别字不会允许编译 - 快速失败(编译时) – 如果您忘记注入一个bean,那么在编译时会失败,而不是在运行时就像XML一样
- 更易于在IDE中导航 – 在bean的构造函数之间来理解依赖关系树。
- 可以轻松debuggingconfiguration启动
我看到它们的缺点并不多,但有一些我能想到的:
- 滥用 – 代码比XML更容易被滥用
- 使用XML,您可以根据在编译期间不可用但在运行时提供的类来定义依赖项。 使用
@Configuration
类时,您必须在编译时提供这些类。 通常这不是问题,但有些情况可能会发生。
底线:在您的应用程序上下文中结合XML, @Configuration
Configuration和注释是完全正确的。 Spring不关心bean声明的方法。