[Spring Boot] 스프링부트 활용 - 기능 소개, Spring Application

dsunni·2020년 8월 6일
2
post-custom-banner

스프링부트가 제공하는 기능

스프링부트가 제공하는 기능은 두 가지로 나뉠 수 있다.

  1. 어떤 기술을 사용하더라도 스프링 부트가 기본적으로 제공하는 핵심 기능들
  2. 각종 기술과 연동해서 사용하는 기능들

스프링부트 핵심 기능각종 기술 연동
SpringApplication스프링 웹 MVC
외부설정스프링 데이터
프로파일스프링 시큐리티
로깅REST API 클라이언트
테스트다루지 않는 내용들
Spring-Dev-Tools

🌵 스프링부트 핵심 기능

SpringApplication

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-spring-application

SpringApplication.run(SprimginitApplication.class, args);

보통 SpringApplication을 실행 할 때 위 한 줄을 추가한다.

하지만 이렇게 하면 SpringApplication이 제공하는 다양한 기능을 커스터마이징해서 사용하기 어렵다.

SpringApplication app = new SpringApplication(Application.class);
app.run(args);

따라서 SpringApplication의 여러 기능들을 입맛에 맞게 사용하고자 할 때는 위와 같이 Spring Application 인스턴스를 생성해 실행하는 편이 좋다.


1. Log Level 설정

아무런 조건 없이 실행하면 기본 로그레벨이 INFO 레벨인 것을 확인할 수 있다.

image

디버거 모드로 Spring Boot Application을 실행하고 싶으면 Edit Configurations...를 선택한 다음

VM options에 -Ddebug 또는 Program arguments에 --debug라고 적어주면 디버거모드로 실행되는 것을 확인할 수 있다. (둘중 하나만 적기)

image

로그도 디버거 레벨까지 출력된다.

image

디버거 레벨 로그에는 어떠한 자동 설정이 적용이 됐는지, 그리고 어떠한 자동설정이 왜 적용이 안 됐는지 볼 수 있다.



2. FailureAnalyzer

애플리케이션 에러가 났을 때 보기 쉽게 출력해주는 기능이다. 기본적으로 Spring Boot Application에는 여러 FailureAnalyzer들이 등록되어있다.



3. Banner

배너란 스프링 부트 애플리케이션 실행 화면에서 나오는 Spring이라는 글자이다. 배너를 바꾸고 싶으면 src - main - resources에 Banner.txt를 만들어서 넣으면 된다.


배너 위치

만약 다른 위치에 Banner를 만들고싶으면 application.properties 파일에

spring.banner.location=classpath:디렉토리\banner.txt
  • 기본 인코딩은 UTF-8이라 시스템 콘솔의 인코딩도 확인해줘야한다.

배너 변수

Banner에서 쓸 수 있는 여러 변수들이 존재한다.

  • ${spring-boot.version} : spring boot 버전 출력
  • 변수들 중 일부는 MANIFEST.MF 파일이 생성되어야지만 출력이된다.

코딩으로 배너 추가

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app 
            = new SpringApplication(Application.class);

        app.setBanner(((environment, sourceClass, out) -> {
            out.println("==============");
            out.println("dunniBanner :)");
            out.println("==============");
        }));
        app.run(args);
    }
}

SpringApplication에서 setBanner를 사용해서 코딩으로 배너를 변경할 수 있다.

image



4. ApplicationEvent

Spring Boot에서는 기본적으로 제공해주는 다양한 시점의 이벤트가 있다. ex) Application이 잘 구동이 되었을 때 or 준비가 됐을 때 등..


ApplicationEvent 등록

@Component
public class DsunniListner implements ApplicationListener<ApplicationStartingEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartingEvent applicationStartingEvent) {
        System.out.println("============================");
        System.out.println("Application is Starting :)");
        System.out.println("============================");
    }
}
  • ApplicationListener 인터페이스를 상속받는 클래스를 만들 때 주의할 점은 어떤 이벤트의 리스너를 만드는지에 대한 타입을 줘야한다.
  • applicationStartingEvent
    • 애플리케이션가 맨 처음에 실행되면 DsunniListner을 실행해준다.
  • @Component 어노테이션을 줘서 DsunniListner를 Bean 으로 등록해주면 등록되어있는 Bean 중에 이 해당한 Event에 대한 DsunniListner를 자동으로 실행해준다.

하지만! 위와같이 등록을 해줘도 실행해보니 열심히 적어둔 리스너가 실행하지 않는다. 왜일까? Event 발생 기점 때문이다


Event 발생 기점 : Application Context 생성

만약 Bean의 리스너 Event가 Application Context가 만들어진 다음에 발생하는 이벤트라면 리스너가 정상적으로 실행된다.

하지만 만약 이벤트가 Application Context가 만들어지기 이전에 발생하는 이벤트라면(ex. ApplicationStartingEvent) Bean으로 등록한다 하더라도 Listner가 동작을 안한다.


Application Context 생성 이전의 이벤트 리스너 등록

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app 
            = new SpringApplication(Application.class);

        app.addListeners(new DsunniListner());
        app.run(args);
    }
}
  • app.addListeners(new DsunniListner());
    • addListners를 통해 리스너 객체를 만들어 넘겨주면 된다
  • 직접적으로 등록할 때는 Bean 등록이 불필요하므로 앞서 DsunniListner에서 추가했던 @Component 어노테이션을 빼주자

image

리스너가 정상적으로 출력되는 것을 확인할 수 있다


Application Context 생성 이후의 이벤트 리스너 등록

Bean으로 등록된 Listner만 생성하면 따로 addListners 없이도 자동으로 등록된다.

package me.dsunni;

import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class DsunniListner implements ApplicationListener<ApplicationStartedEvent> {
    @Override
    public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
        System.out.println("============");
        System.out.println("Started Event :)");
        System.out.println("============");
    }
}
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication app 
            = new SpringApplication(Application.class);
        app.run(args);
    }
}

image

✔️

결론적으로 ApplicationEvent 등록할 때 해당 이벤트가 Application Context 생성 이전의 이벤트인지, 또는 이후의 이벤트인지가 가장 중요하다.



5. WebApplicationType 설정

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

WebApplication에는 세 가지 타입이 있다.

  1. SERVLET
    • Spring MVC가 있다면 기본적으로 SERVLET으로 작동
  2. REACTIVE
    • Spring WebFlux가 있다면 기본적으로 REACTIVE으로 작동
  3. NONE
    • 둘 다 없다면 NONE으로 동작

Type 적용 순서

WebApplication의 Type은 SERVLETREACTIVENONE 순서로 적용된다



6. 애플리케이션 아규먼트 사용하기

image

애플리케이션 아규먼트란 위 Program arguments에서 --로 들어오는 아규먼트를 말한다.

JVM 아규먼트는 -D로 들어오는 아규먼트이다.

Program arguments는 bar로, VM arguments는 foo로 지정해보자.


package me.dsunni;

import org.springframework.boot.ApplicationArguments;
import org.springframework.stereotype.Component;

@Component
public class DsunniListner {
    public DsunniListner(ApplicationArguments arguments) {
        System.out.println("foo : " + arguments.containsOption("foo"));
        System.out.println("bar : " + arguments.containsOption("bar"));
    }
}

어떤 Bean의 생성자가 하나이고, 그 생성자의 Parameter가 Bean일 경우에는 그 Bean을 스프링이 알아서 주입해준다.

Listner를 사용해 아규먼트를 한번 확인해보자.

image

VM arguments는 false, Program arguments는 true를 출력한다. 콘솔에서는 어떨까? jar파일을 만들어서 확인해보자.


image

mvn package를 통해 jar파일을 생성해본다. 참고로 mvn 명령어는 항상 프로젝트 루트에서 실행되어야한다.

실행하면 콘솔에 foo : false, bar : true로 찍힌다. JVM option은 application argument가 아니고, 오로지 -- 옵션을 준 것만 아규먼트로 들어오는 것을 볼 수 있다.


profile
https://dsunni.tistory.com/ 이사갑니답
post-custom-banner

0개의 댓글