백엔드/Spring

[ Spring / 스프링 ] 프로퍼티(.properties) 읽는 방법

토비의 스프링을 보다가 다음에 원리를 설명해 줄 때 필요할 것 같아, 글을 적어 정리를 한다.


 

 

스프링에선 설정을 할때 대표적인 파일형태로 properties파일과 최근엔 yaml파일을 사용한다.

properties파일은 .properties파일로 키=값으로 설정 후 꺼내서 쓰면 된다.

 

<database.properties>

db.driverClass=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/testdb?serverTimezone=UTC
db.username=root
db.password=root

 

 

정의한 properties파일은 @PropertySource 어노테이션을 이용하여 사용할 수 있다.

@PropertySource("/properties/database.properties")
public class AppContext {
...
}

 

@PropertySource로 가져오는 프로퍼티 값은 컨테이너가 관리하는 Environment 타입의 환경 오브젝트에 저장된다.

그리고 스프링에서는 환경 오브젝트는 빈처럼 @Autowired를 통해 필드로 주입이 가능하다.

그래서 2가지의 방법으로 값을 가져올 수 있다.

 

 

  1. 주입받은 Environment 오브젝트의 getProperty() 메소드를 이용하여 값을 가져온다.
    @PropertySource("/properties/database.properties")
    public class AppContext {
    
        @Autowired
        Environment env;
        
        @Bean
        public DataSource dataSource(){
            SimpleDriverDataSource ds = new SimpleDriverDataSource();
    
            try {
                ds.setDriverClass((Class<? extends java.sql.Driver>)Class.forName(env.getProperty("db.driverClass")));
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
            ds.setUrl(env.getProperty("db.url"));
            ds.setUsername(env.getProperty("db.username"));
            ds.setPassword(env.getProperty("db.password"));
    
            return ds;
        }
        
        ....
        
     }


  2.  @Value 어노테이션을 이용하여 값을 가져온다. (치환자를 이용한다.)
    -> 치환자: ${ }안에 넣은 문자열을 엘리머트 값으로 지정한다. ( 예시: ${db.driverClass} )
    치환자를 이용할때에는 PropertySourcesPlaceholderConfigurer를 빈(Bean)으로 정의해줘야한다.
    @PropertySource("/properties/database.properties")
    public class AppContext {
    
        @Value("${db.driverClass}")
        Class<? extends Driver> driverClass;
    
        @Value("${db.url}")
        String url;
    
        @Value("${db.username}")
        String username;
    
        @Value("${db.password}")
        String password;
    
        @Bean
        public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
            return new PropertySourcesPlaceholderConfigurer();
        }
    
        @Bean
        public DataSource dataSource(){
            SimpleDriverDataSource ds = new SimpleDriverDataSource();
    
            ds.setDriverClass(this.driverClass);
            ds.setUrl(this.url);
            ds.setUsername(this.username);
            ds.setPassword(this.password);
    
            return ds;
        }
        
        
        ...
    }​
     

 

@Value 장점

  1. 타입변환이 필요한 프로퍼티를 스프링이 처리해준다.
  2. 지저분한 리플렉션 API나 try/catch 없이 깔끔하게 해준다.

@Value 단점

  1. 클래스에 필드 선언을 해야한다. ( 예제에선 datasource에만 적용함으로 적용범위가 작다. )


ps. 프로젝트를 진행할때는 프로퍼티값을 주입받을때 @Value("${db.properties}")를 그냥 사용했었다.

책을 통해 Environment 객체와 이런 설정들이 존재한다는 사실에 다시 한번 공부에 필요성을 느낀다...