스프링부트가 제공하는 기능
스프링부트가 제공하는 기능은 두 가지로 나뉠 수 있다.
- 어떤 기술을 사용하더라도 스프링 부트가 기본적으로 제공하는 핵심 기능들
- 각종 기술과 연동해서 사용하는 기능들
스프링부트 핵심 기능 각종 기술 연동 SpringApplication 스프링 웹 MVC 외부설정 스프링 데이터 프로파일 스프링 시큐리티 로깅 REST API 클라이언트 테스트 다루지 않는 내용들 Spring-Dev-Tools
SpringApplication.run(SprimginitApplication.class, args);
보통 SpringApplication을 실행 할 때 위 한 줄을 추가한다.
하지만 이렇게 하면 SpringApplication이 제공하는 다양한 기능을 커스터마이징해서 사용하기 어렵다.
SpringApplication app = new SpringApplication(Application.class);
app.run(args);
따라서 SpringApplication의 여러 기능들을 입맛에 맞게 사용하고자 할 때는 위와 같이 Spring Application 인스턴스를 생성해 실행하는 편이 좋다.
아무런 조건 없이 실행하면 기본 로그레벨이 INFO 레벨인 것을 확인할 수 있다.
디버거 모드로 Spring Boot Application을 실행하고 싶으면 Edit Configurations...
를 선택한 다음
VM options에 -Ddebug
또는 Program arguments에 --debug
라고 적어주면 디버거모드로 실행되는 것을 확인할 수 있다. (둘중 하나만 적기)
로그도 디버거 레벨까지 출력된다.
디버거 레벨 로그에는 어떠한 자동 설정이 적용이 됐는지, 그리고 어떠한 자동설정이 왜 적용이 안 됐는지 볼 수 있다.
애플리케이션 에러가 났을 때 보기 쉽게 출력해주는 기능이다. 기본적으로 Spring Boot Application에는 여러 FailureAnalyzer들이 등록되어있다.
배너란 스프링 부트 애플리케이션 실행 화면에서 나오는 Spring이라는 글자이다. 배너를 바꾸고 싶으면 src
- main
- resources
에 Banner.txt를 만들어서 넣으면 된다.
만약 다른 위치에 Banner를 만들고싶으면 application.properties 파일에
spring.banner.location=classpath:디렉토리\banner.txt
Banner에서 쓸 수 있는 여러 변수들이 존재한다.
@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
를 사용해서 코딩으로 배너를 변경할 수 있다.
Spring Boot에서는 기본적으로 제공해주는 다양한 시점의 이벤트가 있다. ex) Application이 잘 구동이 되었을 때 or 준비가 됐을 때 등..
@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("============================");
}
}
@Component
어노테이션을 줘서 DsunniListner를 Bean 으로 등록해주면 등록되어있는 Bean 중에 이 해당한 Event에 대한 DsunniListner를 자동으로 실행해준다.하지만! 위와같이 등록을 해줘도 실행해보니 열심히 적어둔 리스너가 실행하지 않는다. 왜일까? Event 발생 기점 때문이다
만약 Bean의 리스너 Event가 Application Context가 만들어진 다음에 발생하는 이벤트라면 리스너가 정상적으로 실행된다.
하지만 만약 이벤트가 Application Context가 만들어지기 이전에 발생하는 이벤트라면(ex. ApplicationStartingEvent) Bean으로 등록한다 하더라도 Listner가 동작을 안한다.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication app
= new SpringApplication(Application.class);
app.addListeners(new DsunniListner());
app.run(args);
}
}
addListners
를 통해 리스너 객체를 만들어 넘겨주면 된다DsunniListner
에서 추가했던 @Component
어노테이션을 빼주자리스너가 정상적으로 출력되는 것을 확인할 수 있다
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);
}
}
결론적으로 ApplicationEvent 등록할 때 해당 이벤트가 Application Context 생성 이전의 이벤트인지, 또는 이후의 이벤트인지가 가장 중요하다.
@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에는 세 가지 타입이 있다.
WebApplication의 Type은 SERVLET → REACTIVE → NONE 순서로 적용된다
애플리케이션 아규먼트란 위 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를 사용해 아규먼트를 한번 확인해보자.
VM arguments는 false, Program arguments는 true를 출력한다. 콘솔에서는 어떨까? jar파일을 만들어서 확인해보자.
mvn package
를 통해 jar파일을 생성해본다. 참고로 mvn
명령어는 항상 프로젝트 루트에서 실행되어야한다.
실행하면 콘솔에 foo : false, bar : true로 찍힌다. JVM option은 application argument가 아니고, 오로지 --
옵션을 준 것만 아규먼트로 들어오는 것을 볼 수 있다.