spring框架访问properties配置文件的设置方法

方法1:使用占位符${}

1. 在classpath下新建config.properties

jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test

jdbc.initPoolSize=5
jdbc.maxPoolSize=10

is.single=abc

2. 在applicationContex.xml中配置

<!--导入资源文件-->
    <context:property-placeholder location="classpath:config.properties"/>

3. 之后就可以在xml中以及java代码中使用占位符来获取properties值

xml中

<!--配置C3P0数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

java代码中

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class testPropertyConfig {

    @Value("${is.single}")
    String test;

    @Test
    public void test(){
        System.out.println(test);
    }
}

注意事项:

1. 使用@Value,要依赖于组件扫描和自动装配,所以要启用<context:component-scanbase-package="app" />

2.使用context:property-placeholder,在xml配置中只能出现一次,即所有的配置都应该要配置在一个properties文件中,如果你想把不同的配置放置在不同的properties文件中,那么参考方法2

参考:Could not resolve placeholder in string value
 

方法2:使用Spring表达式 SpEL

1. 在classpath下新建config.properties

is.single=abc

新建db.properties

jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///test

jdbc.initPoolSize=5
jdbc.maxPoolSize=10

test=def

2. 在applicationContext.xml中配置

<import resource="classpath:applicationContext-db.xml"/>

<!-- 加载properties文件 -->
    <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="locations">
            <list>
                <value>classpath:config.properties</value>
            </list>
        </property>
    </bean>

在applicationContext-db.xml中配置

<!--导入资源文件-->
    <context:property-placeholder location="classpath:db.properties"/>

3. 之后就可以在xml中以及java代码中来获取不同properties中的值

在applicationContext-db.xml中可以使用占位符

<!--配置C3P0数据源-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

在java代码中,可以使用springExpression Language来指定properties文件来获取,

当然也可以在xml中使用spring Expression Language来获取

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class testPropertyConfig {

    @Value("#{configProperties['is.single']}")
    String test;

    @Value("${test}")
    String test02;

    @Test
    public void test(){
        System.out.println(test);
        System.out.println(test02);
    }
}

使用@PropertySource读取外部配置文件中的k/v,保存到运行的环境变量中。加载完外部的配置文件以后使用${}取出配置文件的值

总结

总结来说,context:property-placeholder是使用占位符来获取properties的值,只能配置一次。

而配置org.springframework.beans.factory.config.PropertiesFactoryBean则可以通过具体bean ID通过spring表达式来获取对应properties中的值

 

 

context:property-placeholder

+占位符

PropertiesFactoryBean

+spring表达式

配置properties个数

1个

多个

xml中

可以使用

可以使用

java代码中 @Value

可以使用

可以使用

 

解析原理

那么以上这种解析方式,原理是什么呢?通过《Spring in action》这本书,可知:

原理是声明属性源并通过Spring的Environment来检索属性,以下是一个基本的spring配置类

@Configuration
@PropertySource("classpath:/com/soundsystem/app.properties")
public class EnvironmentConfig {

  @Autowired
  Environment env;
  
  @Bean
  public BlankDisc blankDisc() {
    return new BlankDisc(
        env.getProperty("disc.title"),
        env.getProperty("disc.artist"));
  }
  
}

属性文件会加载到Spring的Environment中,之后可以通过getProperty()检索属性。

方法3:自定义属性解析

在使用@Value自动注入的时候,存在一个问题:

即如果我想要为private static字段注入值,如果使用@Value,会报cannot autowired static fields错误。原因是当classloader loads the static values,the spring context还没有加载,所以不能注入。

另一种类似的情况。如果我要在类的静态代码块中使用properties中的值,那么@Value由于是在static静态代码块执行之后,才进行自动注入的,那么如何在静态代码块中使用properties中的值呢?可以使用自定义属性的解析。

通过以上的原理,我们可以自定义类来进行属性解析

1. 在classpath下新建config.properties

is.single=abc

2. 在applicationContext中配置

    <!--加载properties文件-->
    <!--在Spring中,使用PropertyPlaceholderConfigurer可以在XML配置文件中加入外部属性文件-->
    <bean id="propertyConfigurer" class="common.sys.PropertyConfigurer">
        <property name="locations">
            <list>
                <value>classpath:config.properties</value>
            </list>
        </property>
    </bean>

3. 写PropertyConfigurer类

/**
 * Created by Administrator on 2017/10/24.
 * PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现
 * 也就是BeanFactoryPostProcessor接口的一个实现
 * <p>
 * PropertyPlaceholderConfigurer可以将上下文(配置文件)中的属性值放在另一个单独的标准java properties文件中去
 */
public class PropertyConfigurer extends PropertyPlaceholderConfigurer {

    private static Map<String, Object> ctxPropertiesMap = new HashMap<>();

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws
            BeansException {
        for (Object key : props.keySet()) {
            String keyStr = key.toString();
            String value = props.getProperty(keyStr);

            ctxPropertiesMap.put(keyStr, value);
        }
        super.processProperties(beanFactoryToProcess, props);
    }

    public static String getProperty(String name, String strDefault) {
        if (null == ctxPropertiesMap.get(name)) {
            return strDefault;
        } else {
            return (String) ctxPropertiesMap.get(name);
        }
    }
}

4. 使用,直接通过我们自己写的getProperty()方法来获取

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class testPropertyConfig {

    @Test
    public void test() {
        System.out.println(PropertyConfigurer.getProperty("is.single", null));
    }
}

其中PropertyConfigurer类仍然继承了Spring自带的类(底层仍然使用了SpringEnvironment),而更彻底的与spring框架解耦的方式则是自己通过stream来读properties文件
参考:http://blog.csdn.net/q542928492/article/details/50673038

工具类

    public class PropertyUtils {  
        private static Map map = null;  
      
        private static void loadFile() {  
            map = new HashMap();  
            try {  
                Properties p = new Properties();  
                p.load(PropertyUtils.class.getClassLoader().getResourceAsStream("config.properties"));  
                Iterator it = p.keySet().iterator();  
                while (it.hasNext()) {  
                    String key = (String) it.next();  
                    String value = p.getProperty(key);  
                    map.put(key, value);  
                }  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }  
      
        public static String getValue(String str) {  
            if (map == null) {  
                loadFile();  
            }  
            return (String) map.get(str);  
        }  
    }  

使用

String url = PropertyUtils.getValue("is.single");

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值