7

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

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

我已经加载myProperties了一个PropertiesFactoryBean<util:properties>来自一个文件的地方,其中包括:

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

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

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

4

3 回答 3

1

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

第二种选择可能是按名称使用注入:

@Resource(name="beanName")

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

于 2012-05-17T21:05:30.770 回答
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<SomeInterface>

实现 FactoryBean 的 bean 的名称将被视为“SomeInterface”,即使它不是。

于 2012-05-17T21:08:42.207 回答
1

Spring 的 Java 配置Bean 定义配置文件正是我想要的(感谢 @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();
    }   
}

对于配置文件,活动配置文件是使用多种方法之一声明的,例如通过系统属性、JVM 属性、web.xml 等。例如,使用 JVM 属性:

-Dspring.profiles.active="dev"
于 2012-05-18T16:51:31.650 回答