将Spring XML文件转换为Spring @Configuration类

在了解Spring @Autowired用法之后,我想为弹簧布线的另一个选项( @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

  • 创建一个@Configuration注释类:

    @Configuration
    public class MyApplicationContext {
    
    }
    
  • 对于每个<bean>标签,创建一个用@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;
    

    这也可以用于SpEL表达式。

  • 为了允许spring将beans容器当作类来处理,我们需要在上下文中放置这个标签来在我们的主要xml中标记这个:

    <context:annotation-config/>
    

    现在您可以像创建简单的bean一样导入@Configuration类:

    <bean class="some.package.MyApplicationContext"/>
    

    有许多方法可以完全避免使用Spring XML,但它们不在本答案的范围内。 您可以在我的博客文章中找到其中的一个选项,我将其作为我的答案的基础。


  • 使用这种方法的优点和缺点

    基本上我发现这种声明bean的方法比使用XML更舒适,因为我看到了一些优点:

  • 错别字 - @Configuration类被编译,错别字不会允许编译
  • 快速失败(编译时) - 如果您忘记注入一个bean,那么您将在编译时失败,而不是在运行时与使用XML相同
  • 更易于在IDE中导航 - 在Bean的构造函数之间了解依赖关系树。
  • 可以轻松调试配置启动
  • 我看到它们的缺点并不多,但我可以想到的有几个:

  • 滥用 - 代码比XML更容易被滥用
  • 使用XML,您可以根据编译时不可用的类来定义依赖项,但在运行时提供这些类。 使用@Configuration类时,您必须在编译时提供这些类。 通常这不是问题,但有些情况可能会发生。
  • 底线:在您的应用程序上下文中结合XML, @Configuration Configuration和注释是完美的。 Spring不关心bean声明的方法。

    链接地址: http://www.djcxy.com/p/67729.html

    上一篇: Converting spring XML file to spring @Configuration class

    下一篇: How to autowire a Spring bean within a controller when testing?