我的目标是一个框架,可以通过属性文件轻松更改具体类型的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。这里最好的做法是什么?
更新:请参阅下面的答案。
答案 0 :(得分:1)
我认为这是不可能的,我倾向于采用的解决方案是使用根据配置属性创建不同对象的工厂(在您的示例中为enabled.type)。
第二种选择可以是按名称使用注射:
@Resource(name="beanName")
最后,如果您使用Spring 3.1+,您可以尝试使用配置文件,并在不同的配置文件中使用不同的bean集,如果这样可以解决您的问题。
答案 1 :(得分:1)
这正是Spring Java Configuration的用例。
或者您也可以选择工厂。
使用:org.springframework.beans.factory.FactoryBean&lt; SomeInterface&gt;
实现FactoryBean的bean的名称将被视为&#34; SomeInterface&#34;即使不是。
答案 2 :(得分:1)
Spring's Java Configuration和Bean 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"