모르지 않다는 것은 아는것과 다르다.

Spring

프로파일과 Resource 인터페이스

채마스 2022. 3. 10. 23:45

프로파일 지정

  • 경우에 따라 다르게 프로파일을 지정하고 싶을 때가 있다.
public class MovieProfile {
    public static final String CSV_MODE = "csv_mode";
    public static final String XML_MODE = "xml_mode";

    // 생성자 차단
    private MovieProfile () {}
}
  • 먼저 위와 같이 상수들을 담는 클래스 만들어 준다.
  • 단지 상수만을 담는 용도이기 때문에 생성자를 막아둔다.
@Profile(MovieProfile.CSV_MODE)
@Repository
public class CsvMovieReader {
    // ... 이하 생략
}
@Profile(MovieProfile.CSV_MODE)
@Repository
public class XMLMovieReader {
    // ... 이하 생략
}
  • 위와 같이 @Profile 애노테이션을 통해 프로파일을 설정할 수 있다.
@ActiveProfiles(MovieProfile.CSV_MODE)
public class test {
    // ... 이하 생략
}
  • 위와 같이 @ActiveProfiles(MovieProfile.CSV_MODE) 을 통해서 프로파일을 지정할 수 있다.
  • 또한 JVM Arguments 를 -Dspring.profiles.active=csv_mode 로 넘겨줌 으로써 프로파일을 지정할 수 있다.
private final Environment env;
movieReader.serMetadata(env.getProperty("movie.metadata"));
@Value("${movie.metadata}")
public void setMetadata(String metadata) {
    this.metadata = metadata;
}
  • 환경 설정정보에서 키에 연결된 값을 읽어 빈 프로퍼티로 설정한다.
@PropertySource("classpath:/application.properties")
  • @PropertySource 애노테이션을 사용해서 프로퍼티파일을 읽어 스프링 환경에 등록할 수 있다.

 

Resource 인터페이스

  • 리소스 인터페이스는 저수준의 리소스 접근을 추상화하고, 더 많은 기능을 제공한다.
  • 스프링은 리소스 인터페이스를 통해서 다양한 외부 자원 정보를 읽어 들일 수 있다.
  • 이름이나, 경로, 설명과 같은 정보들과, Files나 InputStream 객체를 얻을 수도 있다.
  • 또한 리소스의 존재여부터 읽을 수 있는 리소스인지 확인할 수 있는 수단도 제공한다.
  • 또한 리소스 인터페이스를 구현한 다양한 구현체를 제공한다.

 

Resource 구현체 목록

UrlResource

  • java.net.URL을 래핑한 버전, 다양한 종류(ftp:, file:, http:, 등의 prefix로 접근유형 판단)의 Resource에 접근 가능하지만 기본적으로는 http(s)로 원격 접근한다.

ClassPathResource

  • classpath(소스코드를 빌드한 결과(기본적으로 target/classes 폴더)) 하위의 리소스 접근 시 사용한다.

FileSystemResource

  • 이름과 같이 File을 다루기 위한 리소스 구현체다.

SevletContextResource

  • Spring 보다 밖에 있는 Servlet 어플리케이션에서 루트 하위 파일을 다루기 위한 리소스이다.

InputStreamResource

  • InputStream 리소스를 받아올 때 사용한다. 예를들어, 키보드로 입력하는 리소스 등을 받아올 때 사용한다.

ByteArrayResource

  • ByteArrayInput 스트림을 가져오기 위한 구현체다.

 

접두어 사용

  • 접두어를 이용해서 다른 방식의 리소스도 손쉽게 얻을 수 있다.
Resource resource = applicationContext.getResource("classpath:some/resource/path/myTemplate.txt");
Resource resource = applicationContext.getResource("file://some/resource/path/myTemplate.txt");
Resource resource = applicationContext.getResource("https://some/resource/path/myTemplate.txt");
  • 예를들어, 아래와 같이 application.properties가 설정되어 있어서, 클래스 패스 상에 있는 리소스가 아닌 원격지에 있는 리소스라면 아래와같이 원격 리소스를 가져올 수 있다.
movie.metadata=https://www.dropbox.com/bpazz8fffds//movie_metadata.csv?dl=1
@Value("${movie.metadata}")
private String metadata;

@Autoried
ApplicationContext ctx;

Resource resource = ctx.getResource(metadata);
  • 이렇게 되면 원격지에 있는 리소스를 가져올 수 있다.

 

리소스 인터페이스 사용예시

  • Spring ResourceLoader
public class ResourceTest implements ResourceLoaderAware {

    @Value("${movie.metadata}")
    private String metadata;

    private ResourceLoader resourceLoader;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    public Resource getMetadataResource() {
        return resourceLoader.getResource(metadata);
    }

    @PostConstruct
    public void afterPropertiesSet() throws Exception {

        Resource resource = getMetadataSource();
        if (resource.exists() == false) {
            throw new FileNotFoundException(metadata);
        }
        if (resource.isReadable() == false) {
            throw new ApplicationException(String.format("cannot read to metadata. [%s]", metadata));
        }
    }

}
  • setResourceLoader 메소드를 구현함으로써 ResourceLoader 에대한 의존관계를 주입할 수 있다.
  • ResourceLoader 가 아닌 ApplicationContext 로도 대체할 수 있다.




REFERENCES

  • 박용권님의 스프링러너 스프링 아카데미
  • 양세열님의 스프링 프레임워크

'Spring' 카테고리의 다른 글

Null Safety  (0) 2022.03.14
프락시 팩토리빈과 @AspectJ  (0) 2022.03.11
캐시를 사용한 읽기 속도 최적화  (0) 2022.03.10
자바코드로 의존관게 주입하기  (0) 2022.03.10
필터와 인터셉터  (0) 2022.02.27