Java读取配置文件的五种方式

目录

一、ServletContext获取真实路径

二、通过ResourceBundle类获取配置文件资源

三、ClassLoader方式读取

四、使用Sping提供的PropertiesLoaderUtils类

五、@Value("${content}")方式


一、ServletContext获取真实路径

使用request的ServletContext获取文件的绝对路径,通过文件流读出来

优点:1、可以读取任意位置的文件

           2、采用文件流读取,所以可以读取不同格式的文件

缺点:不能在servlet外面读取配置文件,必须要有HttpServletRequest,Web环境适用

public class ServletContextDemo {
    public void readByServletContext(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取文件的绝对地址
        String realPath = request.getServletContext().getRealPath("config.properties");
        // 使用InputStreamReader,指定编码格式,解决中文乱码
        InputStreamReader reader = new InputStreamReader(new FileInputStream(realPath),"GBK");
        Properties pros = new Properties();
        // 加载流文件
        pros.load(reader);
        // 通过key获取对应的值
        String userName = pros.getProperty("userName");
        String chineseName = pros.getProperty("chineseName");
        System.out.println(userName+":"+chineseName);
        System.out.println("真实地址:"+realPath);
    }
}

编写单元测试(使用SpringBoot的方式):

@RunWith(SpringRunner.class)
@SpringBootTest(classes=ServletContextDemo.class)
public class ServletContextDemoTest {

    private MockHttpServletRequest request;
    private MockHttpServletResponse response;

    @Before
    public void setUp(){
        request = new MockHttpServletRequest();
        // 这里设不设置无所谓,主要是使用InputStreamReader时要致指定编码格式
        request.setCharacterEncoding("GBK");
        response = new MockHttpServletResponse();
    }

    @Test
    public void readByServletContext() throws IOException {
        ServletContextDemo demo = new ServletContextDemo();
        demo.readByServletContext(request,response);
    }
}

测试结果:

二、通过ResourceBundle类获取配置文件资源

优点:1、可以以全限定类名的方式加载资源

           2、可以在非web应用里加载资源

缺点:只能加载类下面的资源文件,且只能读取properties文件

使用方式:

1.配置文件放在resource源包下,不用加后缀  
PropertiesUtil.getProfileByResourceBundle("config");  
2.放在包里面的  
PropertiesUtil.getProfileByResourceBundle("com.test.config");

演示代码——获取指定key

public class Demo {
    public static void main(String[] args) throws IOException {
        // 使用文件名读取,不能带文件后缀
        ResourceBundle bundle = ResourceBundle.getBundle("config".trim());
        String userName = bundle.getString("userName");
        String chineseName = bundle.getString("chineseName");// 乱码
        // 解决文件读取乱码
        String newName = new String(chineseName.getBytes("ISO-8859-1"), "GBK");
        System.out.println(userName+" 转码前:"+chineseName+" 转码后:"+newName);
    }
}

测试结果:

演示代码——获取所有key

public class Demo {
    public static void main(String[] args) throws IOException {
        // 使用文件名读取,不能带文件后缀
        ResourceBundle bundle = ResourceBundle.getBundle("config".trim());
        // 拿到所有的key
        Enumeration keys = bundle.getKeys();
        while(keys.hasMoreElements()){// 遍历元素获取值
            String key = keys.nextElement();
            String value = bundle.getString(key);
            System.out.println(key+":"+value);
        }
    }
}

三、ClassLoader方式读取

优点:1、可以在非Web应用中读取配置资源信息,

           2、可以读取任意的资源文件信息

缺点:只能加载类classes下面的资源文件

代码示例:

public class Demo {
    public static void main(String[] args) throws IOException {
        // 类加载器方式,使用相对路径
        InputStream stream = Demo.class.getClassLoader().getResourceAsStream("config.properties");
        // 解决中文乱码,使用了reader指定编码格式
        InputStreamReader reader = new InputStreamReader(stream,"GBK");
        Properties pros = new Properties();
        pros.load(reader);
        // 获取资源
        String userName = pros.getProperty("userName");
        String chineseName = pros.getProperty("chineseName");
    }
}

四、使用Sping提供的PropertiesLoaderUtils类

非常简单的一种方式,引入Spring的相关依赖即可

public class Demo {
    public static void main(String[] args) throws IOException {
        // 使用全限定名
        Properties props = PropertiesLoaderUtils.loadAllProperties("config.properties");
        // 获取资源
        String userName = props.getProperty("userName");
    }
}

五、@Value("${content}")方式

这里使用SpringBoot的方式:

1、首先引入SpringBoot的单元测试依赖


    org.springframework.boot
    spring-boot-starter-test
    test

2、需要读取的配置文件demo.properties

content=this_is_a_String
chineseContent=中文字符串

3、使用注解获取配置文件的内容,创建ValueDemo.java

@PropertySource("classpath:demo.properties")
//@Component
@Configuration
public class ValueDemo {

    @Value("${content}")// 使用注解获取值
    private String content;

    @Value("${chineseContent}")
    private String chineseContent;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getChineseContent() {
        return chineseContent;
    }

    public void setChineseContent(String chineseContent) {
        this.chineseContent = chineseContent;
    }
}

@PropertySource可以指定读取的配置文件通过@Value注解获取值;通常标识在@Configuration配置类上。

@Value注解可以用在字段和方法上,通常用于从属性配置文件中读取属性值,也可以设置默认值。

@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

SpringBoot默认使用一个全局的配置文件,配置文件名是固定的;
1.application.properties
2.application.yml(或者是yaml)

注:当读取的配置文件名不是以上命名时,需要使用@PropertySource注解指定读取的配置文件。

// 读取多个配置文件
@PropertySource(value = { "classpath:demo01.properties", "classpath:demo02.properties"})
public class UserSpringConfig {
    ...
}

@Configuration@Component的区别:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

从定义来看, @Configuration 注解本质上还是 @Component,因此  或者 @ComponentScan 都能处理@Configuration 注解的类。

4、创建SpringBoot启动类MyApplication.java

@SpringBootApplication
@ComponentScan(basePackages = "springdemo")//自动扫描组件,指定包
public class MyApplication {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(MyApplication.class);
        try {
            SpringApplication.run(MyApplication.class);
            logger.info("springBoot启动成功...");
        } catch (Exception e) {
            logger.info("SpringBoot启动失败...");
        }
    }
}

创建一个配置类,在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的

当扫描的文件不在启动类(MyApplication.java)所在的包时,需要在启动类上添加此注解,指明扫描的包。

Java读取配置文件的五种方式_第1张图片

5、启动单元测试获取结果

@RunWith(SpringRunner.class)
@SpringBootTest(classes= MyApplication.class)// classes属性将某些类纳入测试环境的容器中
public class ValueDemoTest {

    @Autowired
    private ValueDemo valueDemo;

    @Test
    public void getContext() throws IOException, InterruptedException {
        // 不能直接new(空指针异常),需要使用注解注入@Autowired
        // ValueDemo valueDemo = new ValueDemo();
        String str = new String(valueDemo.getChineseContent().getBytes("ISO-8859-1"), "GBK");
        System.out.println("获取内容:"+valueDemo.getContent()+" 获取中文内容:"+str);
    }
}

@SpringBootTest注解的参数classes中加入参数,表示将某些类纳入测试环境的容器中。上述案例中,使用@SpringBootTest(classes= ValueDemo.class)也可以得到预期结果

测试结果:

Java读取配置文件的五种方式_第2张图片

你可能感兴趣的:(Java基础,properties,配置文件,SpringBoot,java)