ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [05] Spring Application
    Spring/Spring boot 2020. 5. 28. 08:53
    반응형

    [Spring boot log에 debug log 출력하기]

    Ctrl + Shift + A로 검색창을 열어 edit configurations 라고 입력 후 enter를 누르면 Run/Debug Configurations 메뉴가 열립니다. VM option 또는 Program arguments를 설정해서 Spring boot 실행창에 debug log를 찍을 수 있습니다. 각각의 설정할 값은 다음과 같습니다. Debug log 내용에는 각각의 자동설정이 포함 또는 제외된 원인이 포함됩니다.

    1. VM option : -Ddebug
    2. program argument : --debug

     

    [FailureAnalyzer]

    Application error 발생 시 message를 보기 좋게 출력해주는 기능입니다. Spring boot에서 기본적으로 제공하고 있는 analyzer들이 있으며 필요 시 사용자가 정의한 analyzer를 추가할 수도 있습니다.

     

     

     

    [Banner 설정]

    /src/main/resources 에 banner.txt를 만들고 출력하고자 하는 내용의 text를 저장하면 default banner 대신 저장된 내용의 text로 spring boot banner를 출력할 수 있습니다.

    banner.txt 생성

     

    banner 적용된 결과

    ASCII generator를 사용해서 원하는 banner를 만들어 추가해도 됩니다. 또한 banner 변수를 추가하여 banner를 동적으로 출력할 수도 있습니다. 다음은 spring version을 banner에 추가하는 예입니다.

    banner에 spring boot version 변수 추가
    spring version 변수의 banner 출력

    일부 변수는 MANIFEST.MF file이 있어야 출력됩니다. 예를 들어 ${application.version} 변수를 banner.txt에 추가해도 다시 packaging하지 않으면 MANIFEST.MF file의 내용이 변경되지 않아서 해당 변수는 spring boot banner에 출력되지 않습니다. (Jar packaging에 관한 글)

     

    Spring boot에서 제공하는 보다 많은  banner 변수는 여기를 참고해 주세요. 

     

    만약 /src/main/resources 외에 다른 path에 banner file을 넣고 싶은 경우에는 다음과 같이 application.properties file에 spring.banner.location key에 classpath 기준의 banner file path를 value로 입력해줍니다.

    spring.banner.location=classpath:???/????.txt

     

     

    banner를 사용하지 않기 원하는 경우 SpringApplication 객체의 setBannerMode() method에 매개 값으로 Banner.Mode.OFF를 지정하고 run() method로 application을 실행합니다.

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
    
            SpringApplication app = new SpringApplication(Application.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            app.setBannerMode(Banner.Mode.OFF);	//	①
            app.run(args);
        }
    }

    ① banner를 사용하지 않습니다.

     

     

    SpringApplication 객체의 setBanner() method를 통해 다음과 같이 banner를 customizing할 수도 있습니다.

    @SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
    
            SpringApplication app = new SpringApplication(Application.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            app.setBanner(new Banner() {	//	①
    
                @Override
                public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
                    out.println("###########################");
                    out.println("Dave's spring boot project ");
                    out.println("###########################");
                }
            });
            app.run(args);
        }
    }

    ① Banner 객체를 생성하고 printBanner() method를 overriding하는 것으로 custom한 banner를 출력합니다. 단, banner file이 있는 경우에는 file을 우선하여 banner로 사용합니다.

     

    custom한 banner의 출력

     

     

    [Builder를 통한 spring application 실행]

    SpringApplicationBuilder 객체를 사용해서 spring application을 custom하게 실행하실 수 있습니다. 필요한 경우 banner도 변경 가능합니다. SpringApplicationBuilder를 통한 실행의 예는 다음과 같습니다.

    SpringBootApplication
    public class Application {
    
        public static void main(String[] args) {
    
            new SpringApplicationBuilder()
                    .sources(Application.class)
                    .web(WebApplicationType.NONE)
                    .run(args);
        }
    }
    

     

     

     

    [Application Event와 Listener]

    spring과 spring boot에서 제공하는 application event 들이 있으며 event에 대한 listener를 bean으로 등록하고 실행이 필요할 때 주입받는 형태로 만듭니다. 다음은 ApplicationStartedEvent에 대한 listener를 만들어 정상적으로 동작하는지 확인하는 예제입니다. ApplicationStartedEvent는 spring application이 실행된 후에 발생하는 event이므로 실행이 완료된 시점에 어떤 Event class에 대해 listener가 동작한 것인지 console에 출력하겠습니다.

     

    ApplicationStartedEvent 발생 시 동작할 listener class를 생성합니다.

    @Component	//	①
    public class SampleListener implements ApplicationListener<ApplicationStartedEvent> {	//	②
    
        @Override
        public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {	//	③
            System.out.println("====================================================================================");
            System.out.println(applicationStartedEvent.getClass() + " has occurred.");
            System.out.println("====================================================================================");
        }
    }
    

     

    ① listener를 bean으로 등록합니다.

    ② ApplicationListener<E> type interface를 구현합니다. E는 event type으로 원하는 event를  지정하면 됩니다.

    ③ onApplicationEvent() method를 구현하여 event 발생 시 실행할 로직을 작성합니다.

     

    main class에서 listener를 주입받습니다.

    @SpringBootApplication
    public class Application {
    
        @Autowired
        SampleListener sampleListener;
    
        public static void main(String[] args) {
    
            SpringApplication app = new SpringApplication(Application.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            app.run(args);
        }
    }
    

     위의 코드를 실행하면 의도한대로 application이 실행된 후에 message가 console에 출력됩니다.

    event listener에 의한 출력

    하지만 application context가 생성되기 전에 발생하는 event listener의 경우에는 위와 같이 bean으로 등록해도 이를 처리할 application context가 없는 상태이기 때문에 동작하지 않습니다. 따라서 SpringApplication 객체의 addListeners() method를 통해 listener 객체를 등록해줘야 합니다. ApplicationStarting event를 받는 listener를 예로 살펴봅시다.

     

    위의 SampleListener classs를 다음과 같이 수정합니다.

    //@Component	①
    public class SampleListener implements ApplicationListener<ApplicationStartingEvent> {
    
        @Override
        public void onApplicationEvent(ApplicationStartingEvent applicationStartingEvent) {
            System.out.println("====================================================================================");
            System.out.println(applicationStartingEvent.getClass() + " has occurred.");
            System.out.println("====================================================================================");
        }
    }

    ① 이 listener를 bean으로 등록해도 아무의미가 없으므로 annotation을 제거합니다.

     

    main class를 다음과 같이 변경합니다.

    @SpringBootApplication
    public class Application {
    
        //@Autowired	①
        //SampleListener sampleListener;
    
        public static void main(String[] args) {
    
            SpringApplication app = new SpringApplication(Application.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            app.addListeners(new SampleListener());	//	②
            app.run(args);
        }
    }
    

    ApplicationStarting event를 받는 listener는 bean으로 등록하지 않을 것이기 때문에 주입하지 않습니다.

    ② SpringApplication 객체의 addListeners() method 매개값으로 원하는 listener 객체를 넣어줍니다.

     

    위의 code를 실행하면 spring application이 실행될 때 ApplicationStarting event가 발생하며 이에 대한 listener가 동작하여 console에 그 실행 결과가 출력됩니다.

     

     

    [Web Application Type의 설정]

    Web application type 우선순위는 Servlet, Reactive, None 순 입니다. 

     

     

    [Application argument의 확인]

    application 실행 중에 최초 application 실행에 포함된  "--"로 시작하는  program argument를 확인할 수 있습니다. 참고로 VM option은 program argument가 아닙니다. application 실행 중 program argument를 확인하는 예는 다음과 같습니다.

     

    program argument를 확인하기 위한  bean을 등록하기 위해 ArgumentChecker class를 작성합니다.

    @Component	//	①
    public class ArgumentChecker {
        
        public ArgumentChecker(ApplicationArguments arguments) {	//	②
            System.out.println("vm_options: " + arguments.containsOption("vm_option"));	//	③
            System.out.println("program_arguments: " + arguments.containsOption("program_arguments"));	//	③
        }
    }
    

    ① ArgumentChecker class의 instance를 spring bean으로 등록합니다.

    ② ApplicationArguments class는 bean으로 등록되도록 작성되어있는 class입니다. bean으로 등록하기 위해 생성자를 호출 합니다. ArgumentChecker의 생성자를 호출하면서 ApplicationArguments class의 instance를 매개값으로 넘겨 받으면 bean의 주입이 일어납니다.

    ③ ApplicationArguments 객체의 containOption() method를 사용하여 application 실행 지정한 program option인지 확인합니다.

     

     

    [Application Runner]

    Spring application을 실행한 뒤에 추가로 실행하고 싶은 logic이 있는 경우 ApplicationRunner나 CommandLineRunner interface를 구현한 Runner class를 사용합니다. Runner class (AppRunner) code는 다음과 같습니다.

    @Component
    public class AppRunner implements ApplicationRunner {
        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("Additional logic here");
        }
    }
    

    application을 실행한 결과를 보면 추가로 실행하기 원하는 logic이 실행 되었음을 확인할 수 있습니다.

     

     

     

    'Spring > Spring boot' 카테고리의 다른 글

    [07] Profile  (0) 2020.06.03
    [06] 외부 설정 file (Property)  (0) 2020.06.01
    [04] 독립으로 실행가능한 JAR file  (0) 2020.05.26
    [03] 내장 Web Application Server  (0) 2020.05.20
    [02] Spring boot 자동 설정  (0) 2020.05.15

    댓글

Designed by Tistory.