在spring 3.0中,可以通过使用@value,对一些如xxx.properties文件中的文件,进行键值对的注入。
@Value有两种使用方式:@Value("#{configProperties['t1.msgname']}")或者@Value("${t1.msgname}");
其次,下面我们来看看如何使用这两形式,在配置上有什么区别:
1、@Value("#{configProperties['t1.msgname']}")这种形式的配置中有“configProperties”,其实它指定的是配置文件的加载对象:配置如下:
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="locations"> <list> <value>classpath:/config/t1.propertiesvalue> list> property> bean>
这样配置就可完成对属性的具体注入了;
2、@Value("${t1.msgname}")这种形式不需要指定具体加载对象,这时候需要一个关键的对象来完成PreferencesPlaceholderConfigurer,这个对象的配置可以利用上面配置1中的配置,也可以自己直接自定配置文件路径。
如果使用配置1中的配置,可以写成如下情况:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"> <property name="properties" ref="configProperties"/> bean>
如果直接指定配置文件的话,可以写成如下情况:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer"> <property name="location"> <value>config/t1.propertiesvalue> property> bean>
如果使用注解,可以写成如下情况:
@Configuration @ComponentScan(basePackages = "com.dxz.config") public class ServiceConfiguration2 { public ServiceConfiguration2() { System.out.println("ServiceConfiguration zheli"); } @Bean public static PropertyPlaceholderConfigurer configurer() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); Resource resources = new ClassPathResource( "spring/config.properties" ); ppc.setLocation(resources); return ppc; } @Bean public Configs2 configs2(@Value("${ds.user}") String user, @Value("${key1}") String key1) { Configs2 configs = new Configs2(); configs.setApiKeyId(user); configs.setSecretApiKey(key1); System.out.println("in ServiceConfiguration" + configs); return configs; }
}
示例1:xml中配置PropertyPlaceholderConfigurer
-
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:test.propertiesvalue> list> property> bean>
abc=123
4.读取配置文件内容
-
import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @RequestMapping("/admin/images") @Controller public class ImageAdminController { private String imageDir; @Value("${abc}") public void setImageDir(String val) { this.imageDir = val; } }
示例2:context:property-placeholder
有时候需要从properties文件中加载配置,以前的方式是这样的:
<bean id="jdbcProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath*:/spring/jdbc.propertiesvalue> list> property> bean>
最近发现这样也可以,代码更整洁:
-
<context:property-placeholder location="classpath:spring/jdbc.properties" />
在bean定义中依然可以通过“${}”这种方式来去值:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="initialSize" value="${jdbc.initialSize}" /> <property name="maxActive" value="${jdbc.maxActive}" /> <property name="maxIdle" value="${jdbc.maxIdle}" /> <property name="minIdle" value="${jdbc.minIdle}" /> bean>
说明:
is the XML equivalent to the PropertyPlaceholderConfigurer. So, prefer that. The
simply factories a java.util.Properties instance that you can inject.
示例3:@PropertySource + Environment
在spring3.1中(不是spring3.0)还可以这样:
package com.dxz.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; @Configuration @ComponentScan(basePackages = "com.dxz.config") @PropertySource(value = "classpath:spring/config.properties") public class ServiceConfiguration { @Autowired Environment environment; public ServiceConfiguration() { System.out.println("ServiceConfiguration zheli"); } //@Bean public javax.sql.DataSource dataSource(){ String user = this.environment.getProperty("ds.user"); System.out.println(user); return null; } }
配置文件config.properties:
key1=abc key2=aaaaaaaaaaaaaaaaaaaa key3=bbbbbbbbbbbbbbbbbbbbbbbbbbb key4=cccccccccc ds.user=admin
测试类:
package com.dxz.config; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(ServiceConfiguration.class); ServiceConfiguration hc2 = (ServiceConfiguration) context.getBean("serviceConfiguration"); hc2.dataSource(); } }
结果:
十一月 02, 2017 10:20:43 上午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@3f91beef: startup date [Thu Nov 02 10:20:43 CST 2017]; root of context hierarchy ServiceConfiguration zheli admin
说明:
In Spring 3.0, you can "access" properties defined using the PropertyPlaceHolderConfigurer mechanism using the SpEl annotations:
PropertyPlaceHolderConfigurer可以在xml中配置,如上面提过的。
@Value("${ds.user}") private String user;
If you want to remove the XML all together, simply register the PropertyPlaceholderConfigurer manually using Java configuration. I prefer the 3.1 approach. But, if youre using the Spring 3.0 approach (since 3.1's not GA yet...), you can now define the above XML like this:
如果不采用xml配置,在java编码配置中可以用如下的注册方式来注册PropertyPlaceholderConfigurer,如下
示例4: PropertyPlaceholderConfigurer + @Value
package com.dxz.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; @Configuration @ComponentScan(basePackages = "com.dxz.config") public class ServiceConfiguration2 { public ServiceConfiguration2() { System.out.println("ServiceConfiguration zheli"); } @Bean public static PropertyPlaceholderConfigurer configurer() { PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); Resource resources = new ClassPathResource( "spring/config.properties" ); ppc.setLocation(resources); return ppc; } @Bean public Configs2 configs2(@Value("${ds.user}") String user, @Value("${key1}") String key1) { Configs2 configs = new Configs2(); configs.setApiKeyId(user); configs.setSecretApiKey(key1); System.out.println("in ServiceConfiguration" + configs); return configs; } }
package com.dxz.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class TestConfigs2 { @Autowired Configs2 configs2; @Autowired Configs configs; public void testConfigs2() { System.out.println("configs:"+configs.getApiKeyId()); System.out.println("configs2:"+configs2.getApiKeyId()); } }
package com.dxz.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class Configs { @Value("${key1}") public String apiKeyId; @Value("${ds.user}") public String secretApiKey; public String getApiKeyId() { return apiKeyId; } public String getSecretApiKey() { return secretApiKey; } } package com.dxz.config; //@Component public class Configs2 { public String apiKeyId; public String secretApiKey; public String getApiKeyId() { return apiKeyId; } public void setApiKeyId(String apiKeyId) { this.apiKeyId = apiKeyId; } public String getSecretApiKey() { return secretApiKey; } public void setSecretApiKey(String secretApiKey) { this.secretApiKey = secretApiKey; } @Override public String toString() { return "Configs2 [apiKeyId=" + apiKeyId + ", secretApiKey=" + secretApiKey + "]"; } }
测试类:
package com.dxz.config; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(ServiceConfiguration2.class); TestConfigs2 hc2 = (TestConfigs2) context.getBean("testConfigs2"); hc2.testConfigs2(); } }
结果:
ServiceConfiguration zheli ServiceConfiguration zheli in ServiceConfigurationConfigs2 [apiKeyId=admin, secretApiKey=abc] configs:abc configs2:admin
说明:
1、static类型的会优先在spring容器中注册。Note that the PPC is defined using a static
bean definition method. This is required to make sure the bean is registered early, because the PPC is a BeanFactoryPostProcessor
- it can influence the registration of the beans themselves in the context, so it necessarily has to be registered before everything else.
2、上面示例中有2中场景:
configs是spring容器管理的bean,configs的成员变量通过@Value注解获取配置文件的配置值;
configs2是普通的pojo类,没有注册到spring容器中,在初始化时,通过其创建方法中通过@Value注解获取传入配置文件中的配置值;
不要忘记这时候需要一个关键的对象来完成PreferencesPlaceholderConfigurer来支持;