토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

스프링 부트 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

목차


12.1. Spring Boot Application

이번 섹션은 스프링 부트 애플리케이션과 직접적인 연관이 있는 토픽들을 담고 있다.

12.1.1. Create Your Own FailureAnalyzer

FailureAnalyzer는 기동시 시 예외를 가로채서 FailureAnalysis로 감싸 사람이 읽을 수 있는 메세지로 변환할 때 사용하기 좋은 인터페이스다. 스프링 부트는 애플리케이션 컨텍스트와 관련된 예외나 JSR-303 유효성 검사 등에 활용할 수 있는 analyzer를 제공한다. 물론 직접 만들 수도 있다.

AbstractFailureAnalyzerFailureAnalyzer를 간편하게 사용할 수 있게 확장한 클래스로, 처리할 예외에 지정한 예외 타입이 존재하는 지를 확인해준다. 이 클래스를 상속받으면 실제로 예외가 존재할 때만 처리하도록 구현할 수 있다. 어떤 이유에서든지 예외를 처리할 수 없을 때는 다른 구현체가 예외를 처리할 수 있도록 null을 반환해라.

FailureAnalyzer 구현체는 반드시 META-INF/spring.factories에 등록해줘야 한다. 다음은 ProjectConstraintViolationFailureAnalyzer를 등록하는 예시다:

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.example.ProjectConstraintViolationFailureAnalyzer

BeanFactoryEnvironment에 접근해야 한다면 FailureAnalyzer에서 각각 BeanFactoryAware, EnvironmentAware를 구현하면 된다.

12.1.2. Troubleshoot Auto-configuration

스프링 부트 자동 설정은 “맞는 일을 하기 위해” 최선을 다하지만, 상황에 따라 실패할 수도 있으며, 이유를 알아내기 어려울 때도 있다.

스프링 부트의 모든 ApplicationContext에선 정말 유용한 ConditionEvaluationReport를 사용할 수 있다. 이 리포트는 DEBUG 로그 출력을 활성화하면 볼 수 있다. spring-boot-actuator(액추에이터 챕터 참고)를 사용한다면, 이 리포트를 JSON으로 렌더링해주는 conditions 엔드포인트도 이용할 수 있다. 이 엔드포인트를 활용해 애플리케이션을 디버그하고, 스프링 부트가 런타임에 추가한(그리고 추가하지 않은 기능도 함께) 기능들을 확인해봐라.

소스 코드와 Javadoc을 살펴보면 다른 궁금증도 많이 해결될 거다. 코드를 읽을 때는 경험상 아래 규칙을 기억해두면 좋다:

12.1.3. Customize the Environment or ApplicationContext Before It Starts

SpringApplication은 컨텍스트나 environment를 커스텀할 때 사용할 수 있는 ApplicationListenersApplicationContextInitializers를 가지고 있다. 스프링 부트는 META-INF/spring.factories에서 내부적으로 사용할 여러 가지 커스텀 로직을 로드한다. 별도 커스텀 로직을 등록하는 방법은 여러 가지가 있다:

SpringApplication은 리스너에게 특별한 ApplicationEvent들을 전송하고 (몇 가지 이벤트는 컨텍스트를 만들기 전에 전송한다), ApplicationContext가 게시한 이벤트들을 수신할 리스너도 등록한다. 전체 목록은 ‘스프링 부트 기능’ 섹션에 있는 “애플리케이션 이벤트와 리스너“를 참고해라.

EnvironmentPostProcessor를 사용하면 애플리케이션 컨텍스트를 리프레시하기 전에도 Environment를 커스텀할 수 있다. 모든 구현체는 아래 예시처럼 META-INF/spring.factories에 등록해야 한다:

org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

이 구현체에선 임의의 파일들을 로드해서 Environment에 추가할 수 있다. 예를 들어 아래 코드에선 클래스패스에 있는 YAML 설정 파일을 로드한다:

public class MyEnvironmentPostProcessor implements EnvironmentPostProcessor {

    private final YamlPropertySourceLoader loader = new YamlPropertySourceLoader();

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Resource path = new ClassPathResource("com/example/myapp/config.yml");
        PropertySource<?> propertySource = loadYaml(path);
        environment.getPropertySources().addLast(propertySource);
    }

    private PropertySource<?> loadYaml(Resource path) {
        Assert.isTrue(path.exists(), () -> "Resource " + path + " does not exist");
        try {
            return this.loader.load("custom-resource", path).get(0);
        }
        catch (IOException ex) {
            throw new IllegalStateException("Failed to load yaml configuration from " + path, ex);
        }
    }

}

Environment에는 스프링 부트가 기본으로 로드하는 일반적인 프로퍼티 소스가 전부 준비돼 있다. 그렇기 때문에 environment에서 이런 파일의 위치를 가져올 수도 있다. 위 예제에선 리스트 마지막에 custom-resource 프로퍼티 소스를 추가해서, 다른 위치에 정의되어 있는 일반적인 키가 우선적으로 적용되게 만들고 있다. 직접 구현할 땐 순서를 다르게 정의해도 된다.

@SpringBootApplication 위에 @PropertySource를 선언하면 간편하게 Environment 안에 있는 커스텀 리소스를 로드할 수 있는 것처럼 보일 수도 있지만 권장하지 않는다. 이런 프로퍼티 소스는 애플리케이션 컨텍스트를 리프레시할 때까지 Environment에 추가되지 않는다. 리프레시를 시작하기 전에 읽어가는 logging.*, spring.main.*같은 프로퍼티를 설정하기에는 너무 늦다.

12.1.4. Build an ApplicationContext Hierarchy (Adding a Parent or Root Context)

SpringApplicationBuilder 클래스를 사용하면 ApplicationContext의 부모/자식 계층구조를 만들 수 있다. 자세한 내용은 ‘스프링 부트 기능’ 섹션에 있는 “Fluent Builder API“를 참고해라.

12.1.5. Create a Non-web Application

스프링 애플리케이션이라고 해서 무조건 웹 애플리케이션(또는 웹 서비스)일 필요는 없다. main 메소드에서 몇 가지 코드를 실행하되, 사용할 인프라를 설정하는 용도로 스프링 애플리케이션을 부트스트랩하고 싶을 때는, 스프링 부트의 SpringApplication 기능을 사용하면 된다. SpringApplication은 웹 애플리케이션이 필요한지 아닌지에 따라 ApplicationContext 클래스를 변경한다. 이를 위해 가장 먼저 할 수 있는 일은 서버 관련 의존성(ex. 서블릿 API)을 클래스패스에서 제외하는 거다. 이게 어렵다면 (예를 들어 동일한 코드를 기반으로 애플리케이션을 두 개 실행한다거나) SpringApplication 인스턴스에서 직접 setWebApplicationType(WebApplicationType.NONE)을 호출하거나, applicationContextClass 프로퍼티를 설정해주면 된다 (자바 API나 외부 프로퍼티를 이용해서). 비즈니스 로직으로 실행하고 싶은 애플리케이션 코드는 CommandLineRunner로 구현하고 @Bean 정의로 컨텍스트에 넣어주면 된다.


전체 목차는 여기에 있습니다.

<< >>

TOP