Spring Util:Properties Injection via Annotations into a bean
If I have 2 .properties files setup in my Spring XML as so:
<util:properties id="serverProperties" location="file:./applications/MyApplication/server.properties"/>
<util:properties id="someConfig" location="fi开发者_Python百科le:./applications/MyApplication/config.properties"/>
How can I inject via annotations these properties files into a bean with java.util.Properties
?
How can I grab specific properties via Spring annotations?
Cheers!
@Autowired
@Qualifier("serverProperties")
private Properties serverProperties;
@Autowired
@Qualifier("someConfig")
private Properties otherProperties;
or
@Resource(name = "serverProperties")
private Properties serverProperties;
@Resource(name = "someConfig")
private Properties otherProperties;
Typically, @Autowired is used for by-type autowiring in Spring, and @Resource is used for by-name. @Autowired+@Qualifier can double as by-name autowiring, but it's really meant for by-type autowiring with the ability to fine-tune the type.
As this question has a lot of hits. I thought it would be worthwhile to point out another option using SpEL (Spring Expression Language) - if you need specific properties they can be injected using the @Value annotation on specific bean properties;
class SomeClass {
@Value("#{serverProperties['com.svr.prop']}")
private String aServerCfgProperty;
@Value("#{someConfig['another.config.setting']}")
private String someOtherProperty;
}
You dont need to use the indexing syntax ['index.val']
you can just get it directly;
@Value("#{someConfig}")
private Properties someConfig
@Value("#{serverProperties}")
private Properties svrProps;
I have found this rather useful and moved away from using the properties object directly injected via @Resource/@Autowired.
Another nice reason for using the @Value
with an indexed Properties object is that some IDEs (e.g. IntelliJ) can refactor the actual property names if you also have the .properties file in the project which is nice. Another tip is to use something like EProperties (which extends the native Java Properties object) if you want to do inclusion/nesting/substitution in properties files without using Spring's PropertiesPlaceholderConfigurer
class (which sadly doesnt expose its properties - to use SpEL indexing ['key']
the bean needs to be an instance of Map<>
i.e. extend map which the Java Properties object does)...
Finally, another neat feature with SpEL is you can access properties of beans directly. So say for example if SomeClass
in the example above was a Spring bean e.g. someClass
then in AnotherBeanClass we could have;
@Value("#{someClass.someOtherProperty}")
private String injectedBeanProp
You could also call a getter method:
@Value("#{someClass.getSomeOtherProperty()}")
private String injectedBeanProp
See the SpEL guide here; http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#expressions
You can use @PropertySource
@Configuration
@PropertySource(name = "someName", value = {"classpath:a.properties", "classpath:b.properties"})
public class MyConfiguration {
}
XMl file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:component-scan base-package="com.sha.home" />
<mvc:annotation-driven/>
<util:properties id="dbProp" location="classpath:db.properties" />
<!-- <context:property-placeholder location="classpath:db.properties"/> -->
</beans>
in java file @Value("#{dbProp}") private Properties dbProperties;
System.out.println("urllll"+dbProperties.getProperty("jdbc.url"));
Most of time I encapsulate all properties in to a one utility and used in my apps. In that way you don't need to worry/manage each properties file in app layer. Autowired setProps(...) reads all you loaded util:properties in to the props list.
import java.util.List;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AppProperiesProcessor {
private List<Properties> props;
private Properties mergedProperties;
@Autowired
public final void setProps(List<Properties> props) {
this.props = props;
}
public String getProp(final String keyVal) {
if (null == this.mergedProperties) {
this.mergedProperties = new Properties();
for (Properties prop : this.props) {
this.mergedProperties.putAll(prop);
}
}
return mergedProperties.getProperty(keyVal);
}
}
精彩评论