springboot如何在静态类中获取配置-配置获取全解

  1. springboot如何获取配置文件的配置?
  2. springboot如何在静态类中获取配置?

以下所有示例都通过验证。

1.定义配置文件格式

这里主要指常见的配置文件:properties, yaml.

当然,json也可以作为配置,不过不是首选。

使用的配置文件:

application.properties

api.key=jimo
api.password=password

application.yml

api:
  username: admin

2.动态注入加载

2.1 @Value

@Component
public class ApiConfig {
    @Value("${api.key}")
    private String key;
    @Value("${api.username}")
    private String username;
    @Value("${api.password}")
    private String password;
}

2.2 @ConfigurationProperties(prefix = “api”)

@Component
@ConfigurationProperties(prefix = "api")
public class ApiConfig {
    private String key;
    private String username;
    private String password;
}

2.3 指定配置文件@PropertySource

@PropertySource是spring提供的一个注解,用于把特定配置加载到Environment环境变量里,标准用法是和Configuration一起使用。

注意:@PropertySource(value = {"classpath:test.conf"})对于同一个文件,只需要在一个地方注册,其他地方都可以使用了。

比如:在主类注册

@PropertySource(value = {"classpath:test.conf"})
@SpringBootApplication
public class ConfigTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigTestApplication.class, args);
    }
}

在其他所有bean里都可以使用:

@Component
public class Api {
    @Value("${test.a}")
    private String a;
    @Value("${test.b}")
    private String b;
}

另外:@Value@ConfigurationProperties 都是可以和@PropertySource组合使用的,只是注意配置的重复导致覆盖问题(后加载的会覆盖前面的).

@Data
@Component
@PropertySource(value = {"classpath:test.conf"})
public class Api4Config {
    @Value("${test.a}")
    private String a;
    @Value("${test.b}")
    private String b;
}

3.静态加载

指在静态类中读取配置文件内容

3.1 直接读取

3.1.1 Properties

我们可以使用最基础的Properties工具类:这是java的方式

import java.io.IOException;
import java.util.Properties;
import org.springframework.core.io.ClassPathResource;

/**
 * 直接读取配置文件
 *
 * @author jimo
 * @version 1.0.0
 */
public class RawConfigUtil {

    private static Properties properties = readProperties("test.conf", "test2.conf");

    private static Properties readProperties(String... confFile) {
        final Properties properties = new Properties();
        try {
            for (String path : confFile) {
                final ClassPathResource resource = new ClassPathResource(path);
                properties.load(resource.getInputStream());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return properties;
    }

    public static String getString(String key) {
        return properties.getProperty(key);
    }
}

3.1.2 typesafe.config

或者通过第三方工具:https://github.com/lightbend/config读取

        <dependency>
            <groupId>com.typesafe</groupId>
            <artifactId>config</artifactId>
            <version>1.4.0</version>
        </dependency>

代码:

import com.typesafe.config.Config;
import com.typesafe.config.ConfigFactory;

/**
 * @author jimo
 * @version 1.0.0
 */
public class ConfigUtils {

    private static Config load;

    // 默认加载classpath下的application.*
    static {
        load = ConfigFactory.load();
    }

    /**
     * 读取配置文件中指定Key的值
     *
     * @param key 配置文件中的key
     * @return 指定key的value
     */
    public static String getString(String key) {
        return load.getString(key);
    }

    /**
     * 读取配置文件中指定Key的值
     *
     * @param key 配置文件中的key
     * @return 指定key的value
     */
    public static int getInt(String key) {
        return load.getInt(key);
    }

    /**
     * 读取配置文件中指定Key的值
     *
     * @param key 配置文件中的key
     * @return 指定key的value
     */
    public static boolean getBoolean(String key) {
        return load.getBoolean(key);
    }

}

根据其介绍,默认可以加载这些配置文件:

system properties
application.conf (all resources on classpath with this name)
application.json (all resources on classpath with this name)
application.properties (all resources on classpath with this name)
reference.conf (all resources on classpath with this name)

比较特别的是可以读取json配置,不过笔者用得不多。

3.1.3 小结

但是,这2种方式有以下缺点:

  1. 都不能读取yaml格式的配置
  2. 不能利用springboot从外部和环境变量加载配置的功能,所以只能是死的配置,不够灵活

3.2 使用Environment

要针对spring环境,还是用spring的工具。

Environment是在Spring中代表当前运行的环境,包括:profilesproperties,
它继承了PropertyResolver接口所以才具有读取配置的功能:

public interface Environment extends PropertyResolver {...}

所以,配置的实现其实是PropertyResolver接口的实现类做的。

如果我们能在静态类里持有这个环境,那么就可以获取变量了,恰好spring就提供了这样的接口:EnvironmentAware.

public interface EnvironmentAware extends Aware {

	/**
	 * Set the {@code Environment} that this component runs in.
	 */
	void setEnvironment(Environment environment);
}

这个接口就一个方法:当环境准备好时,会调用这个接口的实现类,然后设置实例。

所以,我们实现这个接口得到Environment:

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

/**
 * @author jimo
 * @version 1.0.0
 */
@Slf4j
@Component
public class MyEnvBeanUtil implements EnvironmentAware {

    private static Environment env;

    @Override
    public void setEnvironment(Environment environment) {
        env = environment;
    }

    public static String getString(String key) {
        return env.getProperty(key);
    }
}

我们实际调用时:

    @Test
    void testEnv() {
        assertEquals("password", MyEnvBeanUtil.getString("api.password"));
        assertEquals("admin", MyEnvBeanUtil.getString("api.username"));
    }

3.3 继承PropertySourcesPlaceholderConfigurer

PropertySourcesPlaceholderConfigurer实现了EnvironmentAware,所以更加丰富,因为可以设置占位符这些信息,用于自定义占位符使用这个,使用方法

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.ConfigurablePropertyResolver;
import org.springframework.core.env.PropertyResolver;
import org.springframework.stereotype.Component;

/**
 * @author jimo
 * @version 1.0.0
 */
@Component
public class PropertyUtil extends PropertySourcesPlaceholderConfigurer {

    private static PropertyResolver propertyResolver;

    @Override
    protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
                                     ConfigurablePropertyResolver propertyResolver) throws BeansException {
        super.processProperties(beanFactoryToProcess, propertyResolver);
        PropertyUtil.propertyResolver = propertyResolver;
    }

    public static String getString(String key) {
        return propertyResolver.getProperty(key);
    }
}

4.总结

本文对spring获取配置做了一些总结,主要有以下方式获取spring的配置:

  1. @Value
  2. @ConfigurationProperties
  3. @PropertySource指定配置文件
  4. Properties读取
  5. typesafe.config读取
  6. EnvironmentAware
  7. PropertySourcesPlaceholderConfigurer

后续会总结springboot的多环境配置。

发布了80 篇原创文章 · 获赞 319 · 访问量 34万+

猜你喜欢

转载自blog.csdn.net/jimo_lonely/article/details/105103232