2023. 12. 12. 00:21ㆍspring
과제
여러 곳(예 : 파일시스템, 클래스패스, 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를 붙여 스프링에게 빈을 생성한 후 이 메서드를 자동 실행하라고 지시한다.
'spring' 카테고리의 다른 글
스프링 레시피 CH2.8 애너테이션을 이용해 POJO 초기화/폐기 커스터마이징하기 (0) | 2023.12.14 |
---|---|
스프링 레시피 CH2.7 프로퍼티 파일에서 로케일마다 다른 다국어 메시지를 해석하기 (0) | 2023.12.14 |
스프링 레시피 CH2.4 @Resource와 @Inject를 붙여 POJO 자동 연결 하기 (0) | 2023.12.11 |
스프링 레시피 CH2.3 POJO 레퍼런스와 자동 연결을 이용해 다른 POJO와 상호 작용하기 (0) | 2023.12.10 |
스프링 레시피 CH2.2 생성자 호출해서 POJO 생성하기 (0) | 2023.12.10 |