SpringBoot学习 (三) 获取配置

 

在实际开发中,很多时候我们需要在配置文件中配置某些配置,以便在程序中获取。

SpringBoot提供获取配置的方式有:

1.使用注解的方式获取指定配置的值

在bean类中定义属性变量,并在字段上面加上注解@Value("${propertyName}")来获取指定配置的值。

如:

配置文件中:

project.author=shaoyu1

Java代码中:

@Value("${project.author}")
private String name;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

2.定义配置类

在系统定义一个类,专门作为配置类,在类上加上注解@ConfigurationProperties(prefix ="指定配置名称前缀")和@Component将之定义为一个bean,其属性名称需要和配置名一一对应。

如:

配置文件中:

my.test1=1111
my.test2=2222
my.test3=3333

Java代码中:

@ConfigurationProperties(prefix ="my")
@Component
public class ConfigBean {

    private String test1;
    private String test2;
    private String test3;
    //省略getter,setter

 

以上两种方法获取配置的方式很唯一,很难变通,一旦我们新增了一个配置,就要重新修改代码,不可拓展。

所以我们需要一些更好的方式来获取配置。

其实在第二种方式中,我们可以稍微修改一下,使用Map作为属性,再在配置文件中以固定的格式编写配置,就可以很顺利的获取固定格式的所有配置信息。

代码如下:

@ConfigurationProperties(prefix ="my")
@Component
public class ConfigBean {
    private static Map<String,String> config;
    
    private Map<String, String> getConfig() {
        return config;
    }

    public void setConfig(Map<String, String> config) {
        this.config = config;
    }
    public static String getString(String key){
        return config.get(key);
    }
}

在配置文件中,我们只需要将所有需要的配置都加上my.config的前缀,那么这个配置类就可以获取所有我们需要的配置信息了。

配置文件如下:

my.config.test1=1111
my.config.test2=2222
my.config.test3=3333

再拓展还可以使用Map<String,Object>来做为属性,只要配置名称能够匹配格式,都是可以获取的。

其实做到这一步还是会觉得很麻烦,还要规定格式之类的,那么还有没有别的方式呢?

当然有。

Spring在加载配置的时候,其实是使用了PropertyPlaceholderConfigurer这个类,这个类是BeanFactoryPostProcessor的子类,其主要的作用是在Spring容器初始化的时候,会读取xml或者annotation对Bean进行初始化。初始化的时候,这个PropertyPlaceholderConfigurer会拦截Bean的初始化,初始化的时候会对配置的${pname}进行替换,根据我们Properties中配置的进行替换。从而实现表达式的替换操作 。比如说我们刚刚提到的第一种方式使用@Value注解,此外,我们在配置文件中也可以使用${pname}进行属性的替换。

在了解了这个类的作用原理之后,我们知道这个类会获取所有的配置信息,所以可以在这个类上面着手,我们翻看源码发现这个类并没有将这些配置信息暴露出来,所以想办法让这些配置信息暴露出来,问题就迎刃而解了。思路如下:

我们写一个类继承PropertyPlaceholderConfigurer,重写processProperties方法,这个方法的第二个参数就是配置信息。在类中新定义一个属性变量,来存储参数的数据,再调用父类的processProperties,在配置文件中自定义这个bean,并指定配置文件,就可以完美获取配置信息了。

代码如下:

/**
 * @Description:
 * @Author: shaoyu1
 * @Date Create in 2018/6/25 16:17
 */
public class PropertiesUtil extends PropertyPlaceholderConfigurer {
    private static Map<String, Object> contextPropertys;

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props) throws BeansException {
        contextPropertys = new HashMap<String, Object>();
        for (Object key : props.keySet()) {
            String keyStr = key.toString();
            String value = props.getProperty(keyStr);
            if (System.getProperties().containsKey(keyStr)) {
                value = System.getProperty(keyStr);
                props.setProperty(keyStr, value);
            }
            contextPropertys.put(keyStr, value);
        }
        super.processProperties(beanFactoryToProcess, props);
    }

    public static Object getValue(String name) {
        return contextPropertys.get(name);
    }

    public static Object getValue(String name,Object defaultValue) {
        Object contextValue=contextPropertys.get(name);
        return contextValue==null?defaultValue:contextValue;
    }
    //show all propertys
    public static void showProperties() {
        Set <String> keys =  contextPropertys.keySet();
        for (String key:keys) {
            System.out.println(key+"="+contextPropertys.get(key));
        }
    }
}
<bean id="propertiesUtil" class="com.yhd.shaoyu.onlineconfig.util.PropertiesUtil">
    <property name="locations">
        <list>
            <value>classpath:application.properties</value>
        </list>
    </property>
    <property name="fileEncoding" value="UTF-8"/>
</bean>

我们来测试一下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class StartApplicationTest {
   @Test
   public void testConfig(){
      System.out.println("配置类:");
      System.out.println(ConfigBean.getString("test1"));
      System.out.println(ConfigBean.getString("test2"));
      System.out.println(ConfigBean.getString("test3"));
      System.out.println("\n注解方式:");
      ConfigBean2 config2 = BeanUtil.getBean(ConfigBean2.class);
      System.out.println(JSON.toJSONString(config2));
      System.out.println("\n继承PropertyPlaceholderConfigurer类的方式:");
      PropertiesUtil.showProperties();
   }
}

运行结果如下:

配置类:
1111
2222
3333

注解方式:
{"name":"shaoyu1"}

继承PropertyPlaceholderConfigurer类的方式:
spring.datasource.data=classpath:data.sql
spring.thymeleaf.servlet.content-type=text/html
logging.config=classpath:logback.xml
spring.thymeleaf.mode=HTML5
spring.datasource.password=shaoyu1
spring.jpa.show-sql=true
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.initialization-mode=never
spring.datasource.username=shaoyu1
spring.thymeleaf.encoding=UTF-8
spring.datasource.schema=classpath:schema.sql
spring.thymeleaf.prefix=classpath:/templates/
spring.datasource.url=jdbc:mysql://localhost:3306/shaoyu1
spring.thymeleaf.suffix=.html
server.port=8080
my.test3=3333
my.config.test1=1111
my.test2=2222
my.test1=1111
my.config.test3=3333
project.author=shaoyu1
my.config.test2=2222

 

第三种方式将配置文件中的所有配置信息都获取到了,我们在开发过程中就可以随便加配置信息啦。

转载于:https://my.oschina.net/siwcky90/blog/1930093

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值