使用注释和属性文件中定义的类型的Spring autowire?

时间:2012-05-17 20:56:45

标签: java spring configuration dependency-injection annotations

我的目标是一个框架,可以通过属性文件轻松更改具体类型的bean。我也更喜欢注释到XML。理想情况下,我会使用@Resource和SpEL的组合,如下所示:

@Resource(type="#{myProperties['enabled.subtype']}")
SomeInterface foo;

我从包含以下内容的文件中加载了myProperties PropertiesFactoryBean<util:properties>

enabled.type = com.mycompany.SomeClassA; // which implements SomeInterface

这不起作用,因为type的参数必须是文字,即不允许SpEL。这里最好的做法是什么?

更新:请参阅下面的答案。

3 个答案:

答案 0 :(得分:1)

我认为这是不可能的,我倾向于采用的解决方案是使用根据配置属性创建不同对象的工厂(在您的示例中为enabled.type)。

第二种选择可以是按名称使用注射:

@Resource(name="beanName")

最后,如果您使用Spring 3.1+,您可以尝试使用配置文件,并在不同的配置文件中使用不同的bean集,如果这样可以解决您的问题。

答案 1 :(得分:1)

这正是Spring Java Configuration的用例。

http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java

或者您也可以选择工厂。

使用:org.springframework.beans.factory.FactoryBean&lt; SomeInterface&gt;

实现FactoryBean的bean的名称将被视为&#34; SomeInterface&#34;即使不是。

答案 2 :(得分:1)

Spring's Java ConfigurationBean Definition Profiles正是我所寻找的(感谢@ Adam-Gent和@Guido-Garcia)。前者似乎是动态元素所必需的,而后者则促进了更好的实践。

这是一个使用Java配置和属性的解决方案:

@Configuration
public class SomeClassConfig {
    @Value("#{myProperties['enabled.subtype']}")
    public Class enabledClass;

    @Bean SomeInterface someBean() 
              throws InstantiationException, IllegalAccessException {
       return (SomeInterface) enabledClass.newInstance();
    }   
}

这是一个带有配置文件的动态解决方案。

@Configuration
@Profile("dev")
public class DevelopmentConfig {
    @Bean SomeInterface someBean() {
       return new DevSubtype();
    }   
}

@Configuration
@Profile("prod")
public class ProductionConfig {
    @Bean SomeInterface someBean() {
       return new ProdSubtype();
    }   
}

使用配置文件,活动配置文件使用variety of methods之一声明,例如通过系统属性,JVM属性,web.xml等。例如,使用JVM属性:

-Dspring.profiles.active="dev"