스프링 레시피 CH2.6 외부 리소스(텍스트, XML, 프로퍼티, 이미지 파일)의 데이터 사용하기

2023. 12. 12. 00:21spring

과제

여러 곳(예 : 파일시스템, 클래스패스, URL)에 있는 외부 리소스(예 : 텍스트, XML, 프로퍼티, 이미지 파일)를 각자 알맞은 API로 읽어들여야 할 때가 있습니다.

해결책

스프링이 제공하는 @PropertySource를 이용하면 빈 프로퍼티 구성용 .properties 파일(키-값)을 읽어들일 수 있다.

또 Resource라는 단일 인터페이스를 사용해 어떤 유형의 외부 리소스라도 경로만 지정하면 가져올 수 있는 리소스 로드 메커니즘이 마련되어 있다.

 

@Value로 접두어를 달리 하여 상이한 위치에 존재하는 리소스를 불러올 수도 있다. 이를테면 파일시스템 리소스는 file, 클래스패스에 있는 리소스는 classpath 접두어로 붙이는 식이다. 리소스 경로는 URL로도 지정할 수 있다.

풀이

@PropertySource와 PropertySorcesPlaceholderConfigurer 클래스를 이용하면 빈 프로퍼티 구성 전용 프로퍼티 파일의 내용(키-값)을 읽을 수 있다.

 

스프링 Resource 인터페이스에 @Value를 곁들이면 어느 파일이라도 읽어들일 수 있다.

 

2.6.1 프로퍼티 파일 데이터를 이용해 POJO 초깃값 설정

프로퍼티 파일에 나열된 값을 읽어 빈 프로퍼티를 설정할 때가 있다. 키-값 형태로 이루어진 DB 설정 프로퍼티나 각종 애플리케이션 설정값이 대부분이다.

가령 discounts.properties 파일에 키-값이 들어 있다고 하자

specialcustomer.discount=0.1
summer.discount=0.15
endofyear.discount=0.2

 

@Configuration
@PropertySource("classpath:discounts.properties")
@ComponentScan("com.spring.study.chapter02.shop")
public class ShopConfiguration {

    @Value("${endofyear.discount:0}")
    private double specialEndofyearDiscountField;

    @Bean
    public static PropertySourcesPlaceholderConfigurer
        propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public Product aaa() {
        Battery p1 = new Battery("AAA", 2.5);
        p1.setRechargeable(true);
        return p1;
    }

    @Bean
    public Product cdrw() {
        Disc p2 = new Disc("CD-RW", 1.5);
        p2.setCapacity(700);
        return p2;
    }

    @Bean
    public Product dvdrw() {
        Disc p2 = new Disc("DVD-RW", 3.0);
        p2.setCapacity(700);
        return p2;
    }
}

 

자바 구성클래스에 값이 "classpath:discount.properties"인 @PropertySource를 붙여 스프링이 파일을 찾게 했다.

 

@PropertySource를 붙여 프로퍼티 파일을 로드하려면 PropertySourcesPlaceholderConfigurer 빈을 @Bean으로 선언해야 한다.

 

스프링은 discounts.properties 파일을 자동으로 연결하므로 이 파일에 나열된 프로퍼티를 빈 프로퍼티로 활용할 수 있다.

 

@Value에 placeholder(자리끼움) 표현식을 넣어 프로퍼티값을 자바 변수에 할당한다.

@Value("{key:default_vlaue}") 구문으로 선언하면 읽어들인 애플리케이션 프로퍼티를 전부 뒤져 주이진 키를 찾고, 매치되는 키가 있으면 그 값을 빈 프로퍼티 값에 할당한다. 못 찾았을 경우에는 default_value 값을 할당한다.

 

프로퍼티 파일 데이터를 빈 프로퍼티 구성 외의 다른 용도로 쓰려면 뒤에 설명할 Resource 메커니즘을 이용한다.

 

2.6.2 POJO에서 외부 리소스 파일 데이터를 가져와 사용하기

애플리케이션 시동 시 클래스패스에 위치한 banner.txt라는 텍스트 파일 안에 문구를 배너로 보여주려고 한다.

***********************
* Welcome to My Shop! *
***********************

 

다음 BannerLoader는 배너를 읽어 콘솔에 출력하는 POJO 클래스다.

public class BannerLoader {
    private Resource banner;

    public void setBanner(Resource banner) {
        this.banner = banner;
    }

    @PostConstruct
    public void showBanner() throws IOException {
        Path path = Paths.get(banner.getURI());

        try(BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        }
    }
}

 

banner 필드는 스프링 Resource형으로 선언했고, 그 값은 빈 인스턴스 생성 시 세터 주입을 사용해 채워진다.

showBanner() 메서드는 배너 파일의 내용을 차레대로 읽어 콘솔에 한 줄씩 출력한다.

 

애플리케이션 시동 시 배너를 보여주기 위해 showBanner() 메서드에 @PostConstruct를 붙여 스프링에게 빈을 생성한 후 이 메서드를 자동 실행하라고 지시한다.