자바 에서 properties 파일 내용 을 읽 는 것 은 더 이상 어 려 운 문제 가 아 닙 니 다.

배경
최근 프로젝트 개발 과정 에서 properties 파일 에서 사용자 정의 변 수 를 정의 하여 자바 프로그램 이 동적 으로 읽 고 변 수 를 수정 하 며 코드 를 수정 하지 않 아 도 되 는 문제 가 발생 했 습 니 다.이번 기회 에 Spring+SpringMVC+Mybatis 통합 개발 프로젝트 에서 자바 프로그램 을 통 해 properties 파일 내용 을 읽 는 방식 으로 정리 하고 분석 하여 여러분 과 공유 하 였 습 니 다.
2.프로젝트 환경 소개
  • Spring 4.2.6.RELEASE
  • SpringMvc 4.2.6.RELEASE
  • Mybatis 3.2.8
  • Maven 3.3.9
  • Jdk 1.7
  • Idea 15.04
  • 3,5 가지 실현 방식
    방식 1.context:property-place holder 를 통 해 프로필 jdbc.properties 의 내용 을 불 러 옵 니 다.
    
    <context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
    위의 설정 과 아래 설정 등 가 는 아래 설정 을 간소화 하 는 것 입 니 다.
    
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="ignoreUnresolvablePlaceholders" value="true"/>
      <property name="locations">
       <list>
         <value>classpath:jdbc.properties</value>
       </list>
      </property>
    </bean>
    주의:이러한 방식 에서 spring-mvc.xml 파일 에 다음 과 같은 설정 이 있다 면 아래 의 빨간색 부분,그 역할 과 원리 가 없어 서 는 안 됩 니 다.
    
    <!--       ,springmvc      Controller   -->
    <context:component-scan base-package="com.hafiz.www" use-default-filters="false">
      <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    방식 2.주 해 를 사용 하여 주입 합 니 다.주로 자바 코드 에서 주 해 를 사용 하여 properties 파일 에 해당 하 는 value 값 을 주입 합 니 다.
    
    <bean id="prop" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
      <!--    PropertiesFactoryBean ,    locations  ,        ,      -->
      <property name="locations">
        <array>
         <value>classpath:jdbc.properties</value>
        </array>
      </property>
    </bean>
    방식 3.util:properties 탭 을 사용 하여 properties 파일 의 내용 을 노출 합 니 다.
    
    <util:properties id="propertiesReader" location="classpath:jdbc.properties"/>
    메모:이 줄 설정 을 사용 하려 면 spring-dao.xml 파일 의 머리 에 아래 빨간색 부분 을 설명 해 야 합 니 다.
    
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:util="http://www.springframework.org/schema/util"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util 
         http://www.springframework.org/schema/util/spring-util.xsd">
    방식 4.Property Placeholder Configurer 를 통 해 컨 텍스트 를 불 러 올 때 properties 를 자체 정의 하위 클래스 의 속성 에 노출 시 켜 프로그램 에서 사용 할 수 있 도록 합 니 다.
    
    <bean id="propertyConfigurer" class="com.hafiz.www.util.PropertyConfigurer">
      <property name="ignoreUnresolvablePlaceholders" value="true"/>
      <property name="ignoreResourceNotFound" value="true"/>
      <property name="locations">
        <list>
         <value>classpath:jdbc.properties</value>
        </list>
      </property>
    </bean>
    사용자 정의 클래스 Property Configurer 의 설명 은 다음 과 같 습 니 다.
    
    package com.hafiz.www.util;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
    
    import java.util.Properties;
    
    /**
     * Desc:properties       
     * Created by hafiz.zhang on 2016/9/14.
     */
    public class PropertyConfigurer extends PropertyPlaceholderConfigurer {
    
      private Properties props;    //   properties    key-value  
    
      @Override
      protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
                  throws BeansException {
        super.processProperties(beanFactoryToProcess, props);
        this.props = props;
      }
    
      public String getProperty(String key){
        return this.props.getProperty(key);
      }
    
      public String getProperty(String key, String defaultValue) {
        return this.props.getProperty(key, defaultValue);
      }
    
      public Object setProperty(String key, String value) {
        return this.props.setProperty(key, value);
      }
    }
    
    
    사용 방식:사용 할 클래스 에@Autowired 주 해 를 사용 하여 주입 하면 됩 니 다.
    방식 5.도구 클래스 PropertyUtil 을 사용자 정의 하고 이 클래스 의 static 정적 코드 블록 에서 properties 파일 내용 을 읽 어 static 속성 에 저장 하여 다른 프로그램 에서 사용 할 수 있 도록 합 니 다.
    
    package com.hafiz.www.util;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.io.*;
    import java.util.Properties;
    
    /**
     * Desc:properties       
     * Created by hafiz.zhang on 2016/9/15.
     */
    public class PropertyUtil {
      private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class);
      private static Properties props;
      static{
        loadProps();
      }
    
      synchronized static private void loadProps(){
        logger.info("    properties    .......");
        props = new Properties();
        InputStream in = null;
        try {
           <!--   ,          properties   -->
          in = PropertyUtil.class.getClassLoader().getResourceAsStream("jdbc.properties");
           <!--   ,       properties   -->
          //in = PropertyUtil.class.getResourceAsStream("/jdbc.properties");
          props.load(in);
        } catch (FileNotFoundException e) {
          logger.error("jdbc.properties     ");
        } catch (IOException e) {
          logger.error("  IOException");
        } finally {
          try {
            if(null != in) {
              in.close();
            }
          } catch (IOException e) {
            logger.error("jdbc.properties         ");
          }
        }
        logger.info("  properties      ...........");
        logger.info("properties    :" + props);
      }
    
      public static String getProperty(String key){
        if(null == props) {
          loadProps();
        }
        return props.getProperty(key);
      }
    
      public static String getProperty(String key, String defaultValue) {
        if(null == props) {
          loadProps();
        }
        return props.getProperty(key, defaultValue);
      }
    }
    
    
    설명:이렇게 되면 이 클래스 가 불 러 올 때 지정 한 위치의 프로필 내용 을 자동 으로 읽 고 정적 속성 에 저장 합 니 다.효율 적 이 고 편리 하 며 한 번 에 불 러 올 때 여러 번 사용 할 수 있 습 니 다.
    4.주의사항 및 건의
    상기 다섯 가지 방식 은 앞의 세 가지 방식 이 비교적 딱딱 하 며,@Controller 주석 이 있 는 Bean 에서 사용 하려 면 SpringMVC 의 프로필 spring-mvc.xml 에서 설명 을 해 야 합 니 다.@Service,@Respository 등 비@Controller 주석 이 있 는 Bean 에서 사용 하려 면 Spring 설정 파일 에서 spring.xml 에서 설명 을 해 야 합 니 다.
    저 는 개인 적 으로 네 번 째 와 다섯 번 째 설정 방식 을 제안 합 니 다.다섯 번 째 가 가장 좋 습 니 다.도구 류 대상 도 주입 하지 않 고 정적 인 방법 으로 직접 얻 을 수 있 습 니 다.그리고 한 번 만 로드 하면 효율 도 높 습 니 다.그리고 앞의 세 가지 방식 이 모두 유연 하지 않 아서@Value 의 키 를 수정 해 야 합 니 다.
    5.사용 가능 한 지 테스트
    1.우선 PropertiesService 를 만 듭 니 다.
    
    package com.hafiz.www.service;
    
    /**
     * Desc:java    properties     service
     * Created by hafiz.zhang on 2016/9/16.
     */
    public interface PropertiesService {
    
      /**
       *          properties     key value
       *
       * @return
       */
      String getProperyByFirstWay();
    
      /**
       *          properties     key value
       *
       * @return
       */
      String getProperyBySecondWay();
    
      /**
       *          properties     key value
       *
       * @return
       */
      String getProperyByThirdWay();
    
      /**
       *          properties     key value
       *
       * @param key
       *
       * @return
       */
      String getProperyByFourthWay(String key);
    
      /**
       *          properties     key value
       *
       * @param key
       *
       * @param defaultValue
       *
       * @return
       */
      String getProperyByFourthWay(String key, String defaultValue);
    
      /**
       *          properties     key value
       *
       * @param key
       *
       * @return
       */
      String getProperyByFifthWay(String key);
    
      /**
       *          properties     key value
       *
       * @param key
       *
       * @param defaultValue
       *
       * @return
       */
      String getProperyByFifthWay(String key, String defaultValue);
    }
    
    
    2.구현 클래스 PropertiesServiceImpl 만 들 기
    
    package com.hafiz.www.service.impl;
    
    import com.hafiz.www.service.PropertiesService;
    import com.hafiz.www.util.PropertyConfigurer;
    import com.hafiz.www.util.PropertyUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    /**
     * Desc:java    properties     service    
     * Created by hafiz.zhang on 2016/9/16.
     */
    @Service
    public class PropertiesServiceImpl implements PropertiesService {
    
      @Value("${test}")
      private String testDataByFirst;
    
      @Value("#{prop.test}")
      private String testDataBySecond;
    
      @Value("#{propertiesReader[test]}")
      private String testDataByThird;
    
      @Autowired
      private PropertyConfigurer pc;
    
      @Override
      public String getProperyByFirstWay() {
        return testDataByFirst;
      }
    
      @Override
      public String getProperyBySecondWay() {
        return testDataBySecond;
      }
    
      @Override
      public String getProperyByThirdWay() {
        return testDataByThird;
      }
    
      @Override
      public String getProperyByFourthWay(String key) {
        return pc.getProperty(key);
      }
    
      @Override
      public String getProperyByFourthWay(String key, String defaultValue) {
        return pc.getProperty(key, defaultValue);
      }
    
      @Override
      public String getProperyByFifthWay(String key) {
        return PropertyUtil.getPropery(key);
      }
    
      @Override
      public String getProperyByFifthWay(String key, String defaultValue) {
        return PropertyUtil.getProperty(key, defaultValue);
      }
    }
    
    
    3.컨트롤 러 클래스 PropertyController
    
    package com.hafiz.www.controller;
    
    import com.hafiz.www.service.PropertiesService;
    import com.hafiz.www.util.PropertyUtil;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    /**
     * Desc:properties     
     * Created by hafiz.zhang on 2016/9/16.
     */
    @Controller
    @RequestMapping("/prop")
    public class PropertyController {
      @Autowired
      private PropertiesService ps;
    
      @RequestMapping(value = "/way/first", method = RequestMethod.GET)
      @ResponseBody
      public String getPropertyByFirstWay(){
        return ps.getProperyByFirstWay();
      }
    
      @RequestMapping(value = "/way/second", method = RequestMethod.GET)
      @ResponseBody
      public String getPropertyBySecondWay(){
        return ps.getProperyBySecondWay();
      }
    
      @RequestMapping(value = "/way/third", method = RequestMethod.GET)
      @ResponseBody
      public String getPropertyByThirdWay(){
        return ps.getProperyByThirdWay();
      }
    
      @RequestMapping(value = "/way/fourth/{key}", method = RequestMethod.GET)
      @ResponseBody
      public String getPropertyByFourthWay(@PathVariable("key") String key){
        return ps.getProperyByFourthWay(key, "defaultValue");
      }
    
      @RequestMapping(value = "/way/fifth/{key}", method = RequestMethod.GET)
      @ResponseBody
      public String getPropertyByFifthWay(@PathVariable("key") String key){
        return PropertyUtil.getProperty(key, "defaultValue");
      }
    }
    
    
    4.jdbc.properties 파일
    
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://192.168.1.196:3306/dev?useUnicode=true&characterEncoding=UTF-8
    jdbc.username=root
    jdbc.password=123456
    jdbc.maxActive=200
    jdbc.minIdle=5
    jdbc.initialSize=1
    jdbc.maxWait=60000
    jdbc.timeBetweenEvictionRunsMillis=60000
    jdbc.minEvictableIdleTimeMillis=300000
    jdbc.validationQuery=select 1 from t_user
    jdbc.testWhileIdle=true
    jdbc.testOnReturn=false
    jdbc.poolPreparedStatements=true
    jdbc.maxPoolPreparedStatementPerConnectionSize=20
    jdbc.filters=stat
    #test data
    test=com.hafiz.www
    
    
    5.프로젝트 결과 도
      
    6.프로젝트 다운로드:demo http://xiazai.jb51.net/201612/yuanma/propertiesConfigurer_jb51.zip
    7.테스트 결과
    첫 번 째 방식
      
    두 번 째 방식
     
    세 번 째 방식
      
    네 번 째 방식
      
    다섯 번 째 방식
      
    총화
    이번 정리 와 테스트 를 통 해 우 리 는 Spring 과 SpringMVC 의 부자 용기 관계 와 context:component-can 태그 팩 을 스 캔 할 때 가장 무시 하기 쉬 운 use-default-filters 속성의 역할 과 원 리 를 이해 했다.다시 겪 는 문 제 를 더욱 잘 포 지 셔 닝 하고 신속하게 해결 할 수 있다.아무튼 짱 이다~~~
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기