Java 如何使用注释使用配置文件中的变量限定自动连接属性?

Java 如何使用注释使用配置文件中的变量限定自动连接属性?,java,spring,annotations,Java,Spring,Annotations,我的具体问题是,我配置了两个实现相同接口的bean,第三个bean具有该接口类型的属性。我使用config属性注入属性。因此,假设RemoteDataSource和LocalDataSource实现IDataSource,并且dao1具有IDataSource类型的属性,我的XML配置可能如下所示: <bean id="datasource1" class="com.foo.RemoteDataSource"> <property name="url">${url}&

我的具体问题是,我配置了两个实现相同接口的bean,第三个bean具有该接口类型的属性。我使用config属性注入属性。因此,假设RemoteDataSource和LocalDataSource实现IDataSource,并且dao1具有IDataSource类型的属性,我的XML配置可能如下所示:

<bean id="datasource1" class="com.foo.RemoteDataSource">
  <property name="url">${url}</property>
</bean>
<bean id="datasource2" class="com.foo.LocalDataSource">
  <property name="path">${filepath}</property>
</bean>
<bean id="dao1" class="com.foo.MyDAO">
  <property name="dataSource">${datasource}</property>
</bean>

注意:现在是春季3,我认为这是不可能的。即使在完全由注释驱动的CDI中,根据配置切换bean也是通过xml完成的。

您有任何xml配置吗?我假设你有一个数据源

硬编码数据源的限定符,然后在xml配置中创建别名,该别名基于属性进行别名

差不多

@Autowired
@Qualifier("designatedDatasource")
public void setDataSource(IDataSource datasource) {...}
然后在xml中:

<alias name="${dataSource}" alias="designatedDatasource"/>

我很确定spring开发人员考虑过允许您按照您指定的方式进行开发,但就我个人而言,我宁愿不这样做。确定$dataSource值从何处获得可能会非常棘手。我还认为,在注释中支持可配置属性会使事情变得太复杂,并允许太多潜在的混淆。

因此,我的解决方案是:

@Autowired
public void setDataProviders(Map<String,IDataProvider> dataProviders) {
    this.dataProviders = dataProviders;
}

@Autowired
@Value("${cms}")
public void setDataProviderName(String dataProviderName) {
    this.dataProviderName = dataProviderName;
}

public IDataProvider getDataProvider() {
    return dataProviders.get(dataProviderName);
}
@Autowired
公共void setDataProviders(映射数据提供程序){
this.dataProviders=数据提供者;
}
@自动连线
@值(“${cms}”)
public void setDataProviderName(字符串dataProviderName){
this.dataProviderName=dataProviderName;
}
公共IDataProvider getDataProvider(){
返回dataProviders.get(dataProviderName);
}

注意:我将命名改为DataProvider,以消除与规范数据源之间的歧义。实际上,它只是一个自制的REST客户端。

我针对我遇到的类似问题做了一些变通

我的问题是我有三个服务实现,比如ServiceImpl1、ServiceImpl2和ServiceImpl3和 在PlaceHolder my.serviceImpl的属性文件中,我可能有如下值

my.serviceImpl = serviceImpl1

因此,在我的控制器中,我应该能够使用@Qualifier(${my.my.serviceImpl}) 但这不起作用,我甚至尝试了@value for,但也失败了

最后,我在ApplicationConf.java中将bean定义为

@Bean(name = "myServiceImpl")
public Service myService() {

    String beanName = environment.getProperty("my.serviceImpl");

        if (beanName.equals("serviceImpl1")) {
            return new serviceImpl1();
        }
        else if(beanName.equals("serviceImpl2")){
            return new serviceImpl2();
        }
        else if(beanName.equals("serviceImpl3")){
            return new serviceImpl3();
        }


}
在我的控制器中,我使用限定符作为

@Autowired
@Qualifier("myServiceImpl")
Service myService;

但不确定这是否是最好的方法。

对于Spring 3.1,您的问题可以通过以下方式解决:


我认为这是注释配置不合适的一个很好的例子。XML和注释一起工作——利用它们各自的优势。
my.serviceImpl = serviceImpl3
@Bean(name = "myServiceImpl")
public Service myService() {

    String beanName = environment.getProperty("my.serviceImpl");

        if (beanName.equals("serviceImpl1")) {
            return new serviceImpl1();
        }
        else if(beanName.equals("serviceImpl2")){
            return new serviceImpl2();
        }
        else if(beanName.equals("serviceImpl3")){
            return new serviceImpl3();
        }


}
@Autowired
@Qualifier("myServiceImpl")
Service myService;
<bean id="dao1" class="com.foo.MyDAO">
   <property name="dataSource">${datasource}</property>
</bean>

<beans profile="remote">
   <bean id="datasource1" class="com.foo.RemoteDataSource">
      <property name="url">${url}</property>
   </bean>
<beans>

<beans profile="local">
    <bean id="datasource2" class="com.foo.LocalDataSource">
      <property name="path">${filepath}</property>
    </bean>
<beans>
@Autowired
public void setDataSource(IDataSource datasource) {...}