[英]How can I qualify an autowired property with a variable from a config file using annotations?
My specific problem is that I have configured two beans that implement the same interface and I have a third bean that has a property of that interface's type. 我的具体问题是我已经配置了两个实现相同接口的bean,并且我有第三个bean,它具有该接口类型的属性。 I inject the property using a config property.
我使用config属性注入属性。 So, assuming RemoteDataSource and LocalDataSource implement IDataSource and dao1 has a property of type IDataSource, my XML config might look like this:
因此,假设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>
With url, filepath and datasource being defined in an included properties file. 使用url,filepath和datasource在包含的属性文件中定义。 We are now making a push for annotation-driven configuration and I'm not sure how to annotate my dao to put the data source configured in the property file.
我们现在正在推动注释驱动的配置,我不知道如何注释我的dao以将数据源配置在属性文件中。 I want to do something like this, but it is evidently not allowed:
我想做这样的事情,但显然不允许:
@Autowired
@Qualifier("${datasource}")
public void setDataSource(IDataSource datasource) {...}
NB: this is spring 3 注意:这是春天3
Do you have any xml configuration? 你有任何xml配置吗? I'd assume you do as you have a data source.
我假设你做了,因为你有一个数据源。
Hard code the Qualifier for the datasource and then create an alias in your xml configuratation which aliases based on the property. 硬编码数据源的限定符,然后在xml配置中创建别名,该别名基于属性进行别名。
Something like 就像是
@Autowired
@Qualifier("designatedDatasource")
public void setDataSource(IDataSource datasource) {...}
And then in xml: 然后在xml中:
<alias name="${dataSource}" alias="designatedDatasource"/>
I'm pretty sure the spring developers considered allowing you to do it the way you specified, but personally, I would prefer not to. 我很确定春天开发人员考虑允许你按照你指定的方式去做,但就个人而言,我宁愿不这样做。 Working out where it is getting that $dataSource value from could end up quite tricky.
解决它从哪里获得$ dataSource值可能会变得非常棘手。 I also think that supporting configurable properties in annotations would complexify things too much and allow for too much potential confusion.
我还认为,在注释中支持可配置属性会使事情过于复杂化,并且会产生太多潜在的混淆。
My solution was thus: 我的解决方案是:
@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);
}
NB: I changed that naming to DataProvider to disambiguate from the canonical DataSource which this isn't. 注意:我将命名更改为DataProvider以消除规范DataSource的歧义,而不是。 It's actually just a homemade REST client.
它实际上只是一个自制的REST客户端。
I did some work around for the similar problem I had. 我做了一些解决我遇到的类似问题的工作。
My problem was I had three implementation for the Service say ServiceImpl1,ServiceImpl2 and ServiceImpl3 and in the properties file for place holder my.serviceImpl I may have values like 我的问题是我有三个服务实现说ServiceImpl1,ServiceImpl2和ServiceImpl3,并且在占位符my.serviceImpl的属性文件中我可能有类似的值
my.serviceImpl = serviceImpl1
or 要么
my.serviceImpl = serviceImpl2
or 要么
my.serviceImpl = serviceImpl3
So in my controller I should be able to use @Qualifier(${my.my.serviceImpl}) but this didn't worked, I even tried @value for but it also failed. 所以在我的控制器中,我应该可以使用@Qualifier($ {my.my.serviceImpl}),但这没有用,我甚至试过@value但它也失败了。
So finally I defined bean in my ApplicationConf.java as 所以最后我在我的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();
}
}
And in my controller I used qualifier as 在我的控制器中,我使用限定符作为
@Autowired
@Qualifier("myServiceImpl")
Service myService;
Not sure though if this is the best way to do it. 不确定这是否是最好的方法。
I don't think this is possible. 我不认为这是可能的。 Even in CDI, which is entirely annotation-driven, switching beans depending on configuration is done via xml.
即使在完全注释驱动的CDI中,依赖于配置的切换bean也是通过xml完成的。
For Spring 3.1 your problem is solved by Spring profiles : 对于Spring 3.1,您的问题由Spring配置文件解决:
<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>
No @Qualifier needed, only one IDataSource in every profile. 不需要@Qualifier,每个配置文件中只有一个IDataSource。
@Autowired
public void setDataSource(IDataSource datasource) {...}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.