问题
Edit: Here is some explanation of why the accepted answer works for me, and possibly what could be a problem for others.
In my foo-app-servlet.xml, i have this line:
<context:component-scan base-package="com.foo.app" />
When I used spring2 before, all my service beans came from applicationContext.xml, but now they are being brought in directly in the foo-app-servlet.xml. On my project servlets have their own set of overrides, so I need to override in the servlet override file instead of the applicationContext override file.
When overriding, if you haven't named your component then it does indeed use the lowercase version of it, so to override OrderService.foo, you do this:
orderService.foo=bar
End Edit
I'm working an a project that was upgraded from spring 2.5 to spring 3 and thus has both xml and annotation based config. We previously have used PropertyOverrideConfigurer to change properties in different environments to great success. I'm now working on code that uses authorize.net and I need to make sure I don't send anything to them from the development environment.
In order to accomplish this I want to override my 'testMode' property with PropertyOverrideConfigurer. This works great for beans that are configured via xml, but I can't figure out how to do it with annotation configured classes.
This is my override snippet from applicationContext.xml:
<bean class="org.springframework.beans.factory.config.PropertyOverrideConfigurer">
<property name="location" value="file:${user.home}/override.properties" />
<property name="localOverride" value="true" />
<property name="ignoreResourceNotFound" value="true" />
</bean>
Here is the class with the property I want to override:
@Component
public class OrderService {
private static Log logger = LogFactory.getLog(OrderService.class);
@Autowired @Qualifier("OrderDAO") private OrderDAO orderDao;
@Autowired private SiteManager siteManager;
String authorizenetProperties = "classpath:authorizenet.properties";
private Boolean testMode = false;
public Boolean getTestMode() {
return testMode;
}
public void setTestMode(Boolean testMode) {
this.testMode = testMode;
}
}
I've tried a few things that didn't work:
com.foo.services.OrderService.testMode=true
OrderService.testMode=true
Is it possible to do what I want to do here? Does spring 3 have a new preferred way of doing this?
回答1:
The PropertyOverrideConfigurer uses the key in your properties file as the bean name.bean property. When @Component autoscans your configuration, Spring will name the bean as the unqualified class name starting with a lower case. In your case, the OrderService bean should be named orderService. So, the following should work.
orderService.testMode=true
You can also name the bean by passing a name to the Component annotation like @Component("OrderService") or @Component("com.foo.services.OrderService"). None of this is new in Spring 3.x.
Hope this helps
回答2:
Posting this non-optimal solution:
You can work around this with another bean:
applicationContext.xml:
<bean id="SiteProperties" class="com.foo.utilities.SiteProperties">
<property name="serviceUrl" value="http://localhost:8080" />
<property name="authorizationTestMode" value="false" />
</bean>
OrderService.java:
@Component
public class OrderService {
private static Log logger = LogFactory.getLog(OrderService.class);
@Autowired @Qualifier("OrderDAO") private OrderDAO orderDao;
@Autowired private SiteManager siteManager;
@Autowired private SiteProperties siteProperties;
String authorizenetProperties = "classpath:authorizenet.properties";
}
So just create an xml-configured bean and inject into you annotation-configured bean.
I'd still like to know the "right" way to do this if anyone knows.
Thanks!
来源:https://stackoverflow.com/questions/10034732/using-propertyoverrideconfigurer-with-annotated-classes-in-spring-3