728x90
Spring Boot의 공식 문서 :Spring Boot Reference Documentation
그 중 Documentation Overview 문서 : Documentation Overview (spring.io)
4번 항목에서 Spring Boot를 사용하려는 개발자는
SpringApplication 항목 문서를 읽어보라고 나와 있다
Spring Boot의 공식 문서 :Spring Boot Reference Documentation
그 중 Core Features 문서 : Core Features (spring.io)
Core Features의 1번 항목 : Core Features (spring.io) - SpringApplication
SpringApplication
SpringApplication 클래스는 Spring을 시작하는 편리한 방법을 제공한다.
많은 상황에서 SpringApplication.run 정적 메서드에 위임할 수 있다.
아래 이후 설명할 내용들은 SpringApplication 클래스가 제공하는 기능 및 특징 등에 대해 설명하는 것이다
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
1. 시작 실패
- 시작에 실패할 경우 FailureAnalyzer가 에러 메세지와 해결방법을 알려준다. 아래는 예시이다.
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that is listening on port 8080 or configure this application to listen on another port.
- 만약 FailureAnalyzer가 알수 없는 에러라면 전체 내역을 볼 수 있다.
속성파일 application.properties에 아래와 같이 추가해준다.
logging.level.root=debug
2. 지연 초기화(Lazy Initialization)
- lazy initialization, 즉 지연 초기화가 활성화 되면, bean들이 시작 후에 필요한 경우에 생성된다.
- 장점은 시작 시간이 짧아지는 것이다. web application에서 web 관련 bean들이 http 요청이 오기 전까지 초기화(생성)되지 않는다.
- 단점, 빈들이 나중에 초기화되기 때문에 문제 발생의 확인이 늦어진다. 그래서 기본적으로는 Lazy initialization은 꺼져 있다.
- 켜는 방법은
1. SpringApplicationBuilder의 lazyInitialization 메소드 사용
2. SpringApplication에서 setLazyInitialization 메소드 사용
3. spring.main.lazy-initialization=true 설정 세가지 방법이 있다.
Lazy initialization을 켜고 @Lazy(false)로 일부만 시작 시 초기화도 가능하다.
3. 배너 변경하기
- classpath에 banner.txt를 추가하면 시작 시 나오는 배너를 바꿀 수 있다.
또는 spring.banner.location에 파일경로를 추가하면 된다.
파일은 UTF-8 이어야 한다. spring.banner.charset에 설정할 수 있다. - banner.txt 안에 application의 정보도 출력할 수 있다.
예) ${spring-boot.version} 는 사용되는 spring boot 버전이 출력된다.
>> "spring-boot-version : ${spring-boot.version}" - SpringApplication.setBanner(…) 또는 org.springframework.boot.Banner 인터페이스의 printBanner() 를 구현하면
코드로도 banner 변경이 가능하다 - spring.main.banner-mode 속성으로 log로 출력 여부까지 설정할 수 있다.(on, off로 설정)
4. SpringApplication 커스텀
- SpringApplication의 기본 값을 커스텀하고 싶다면, instance를 만들고 커스텀하면 된다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
또는 application.lproperties 파일로 설정값을 바꾸는 방법도 있다
5. Fluent Builder API
- 순차적인 빌드가 필요할 경우 SpringApplicationBuilder를 사용하면 된다.
아래는 예시 2가지
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
public class App {
public static void main(String[] args) {
new SpringApplicationBuilder()
.parent(ParentConfig.class).web(WebApplicationType.NONE)
.child(WebConfig.class).web(WebApplicationType.SERVLET)
.sibling(RestConfig.class).web(WebApplicationType.SERVLET)
.run(args);
}
}
6. Application 사용 가능 여부
”actuator”를 사용한다면 Spring의 정보를 읽을 수 있는 url endpint를 제공한다.
- 1. Liveness state
“Liveness” state는 잘 동작하고 있는지 또는 복구중인지를 알려준다.
만약 “Liveness”가 망가졌다면, 복구를 못하고 있는것이다. 재시작이 필요하다.
Spring Boot application의 상태는 ApplicationContext로 표현된다.
Spring Boot는 application context가이 성공적으로 시작됐다면, 정상인 것으로 생각한다. - 2. Readiness State
“Readiness” state는 트래픽을 다룰 준비가 돼있는지 말해준다.
Readiness의 실패는 트래픽을 지금 처리할 수 없다는 것이다.
주로 시작시에 CommandLineRunner와 ApplicationRunner가 동작 중이거나,
application이 여유가 없다고 판단할 시에 발생한다. - 3. Managing the Application Availability State
ApplicationAvailability 인터페이스를 주입 함으로써 현재 availability를 알아낼 수 있다.
application의 state를 듣거나 업데이트하길 원할 때 아래와 같이 하면된다. - application에게 readiness state를 읽어서 파일로 내보내는 예시
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC:
// create file /tmp/healthy
break;
case REFUSING_TRAFFIC:
// remove file /tmp/healthy
break;
}
}
}
- application에게 회복 불가능한 상태(LivenessState.BROKEN)를 알리는 예시
@Component
public class MyLocalCacheVerifier {
private final ApplicationEventPublisher eventPublisher;
public MyLocalCacheVerifier(ApplicationEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void checkLocalCache() {
try {
// ...
}
catch (CacheCompletelyBrokenException ex) {
AvailabilityChangeEvent.publish(this.eventPublisher, ex, LivenessState.BROKEN);
}
}
}
7. Application Events and Listeners
- Spring Framework events에 더해, SpringApplication 클래스도 event들을 보낸다
- 몇몇 event 들은 ApplicationContext가 생성되기 전에 발생해서
이 event 들에 대한 listener를 Bean으로 등록할 수 없다. - 그럴땐 SpringApplication.addListeners(…) 메서드나 SpringApplicationBuilder.listeners(…)를 사용할 수 있다.
- application 시작 시 event 발생 순서
1. ApplicationStartingEvent : 시작. listener와 initializer 등록 전
2. ApplicationEnvironmentPreparedEvent : Environment가 알려졌지만, context는 생성 전
3. ApplicationContextInitializedEvent : ApplicationContext가 준비되고. ApplicationContextInitializers가 불러와졌으나, bean의 정의는 불러오기 전
4. ApplicationPreparedEvent : refresh 는 시작됐으나 bean 정의는 불러오기 전
5. ApplicationStartedEvent : context가 refresh 된 후, application 과 command-line runner는 불로오기 전
6. AvailabiliyChangeEvent : LivenessState.CORRECT 바로 후에 발생
7. ApplicationReadyEvent : an application & commad-line runner가 불러진 후
8. AvailabilityChangeEvent : ReadinessState.ACCEPTING_TRAFFIC 바로후
9. ApplicationFailedEvent : 시작 도 중 예외 발생 시
위 이벤트 들은 SpringBoot의 SpringApplication와 연관된 이벤트만 포함한다.
아래 이벤트들은 ApplicationPreparedEvent 후, ApplicationStartedEvent 전 사이에 발생
1. WebServerInitializedEvent : WebServer가 준비 됐다는 이벤트
Servelt은 ServletWebServerInitializedEvent
Reactive는 ReactiveWebServerInitializedEvent
2. ContextRefreshedEvent : ApplicationContext 가 refresh 됐을 때
- Event Listener는 기본적으로 같은 스레드를 사용하기 때문에 무거운 작업을 하면 안된다.
필요하면 대신에 command-line runner를 고려해보는 것이 좋다.(10번) - Application event는 Spring Frame work의 이벤트 발생 메커니즘을 사용했기 때문에
하위 리스너에게 발생한 이벤트는 상위 리스너에게도 전달된다.
위 두개를 구분하기 위해서는 context 비교를 해야한다.
리스너의 context는 ApplicationContextAware를 구현하거나 리스너를 Bean으로 등록하면 주입할 수 있다.
8. Web Environment
- SpringApplication은 올바른 ApplicationContext 타입을 만들기 위해서 노력한다.
- 타입은 결정하기 위한 알고리즘은 아래와 같다.
Spring MVC가 존재하면 AnnotationConfigServletWebServerApplicationContext 를 사용
Spring MVC가 없고 WebFlux가 있으면, AnnotationConfigReactiveWebServerApplicationContext를 사용
그 외 경우에는 AnnotationConfigApplicationContext 를 사용한다. - 즉, SpringMVC와 SpringWebClient를 함께 사용하면, 기본적으로 SpringMVC가 사용된다.
override 하고 싶다면 setWebApplicationType(WebApplicationType)를 호출하면 된다.
setApplicationContextFactory(...)를 호출하여 사용되는 ApplicationContext 유형을 완전히 제어할 수도 있다.
9. Accessing Application Arguments
- SpringApplication.run(…)으로 전달되는 인자에 접근하고 싶다면, ApplicationArguments bean을 주입할 수 있다. ApplicationArguments interface는 String[] 과 parsed, non-parsed 모두 접근할 수 있다.
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
// if run with "--debug logfile.txt" prints ["logfile.txt"]
}
}
10. Using the ApplicationRunner or CommandLineRunner
- ApplicationRunner or CommandLineRunner 인터페이스는 SpringApplication.run 전에 불려진다.
(시작 후, 그리고 트래픽을 받기 전에 동작해야하는 것에 알맞다) - CommandLineRunner 인터페이스는 application arguments에 대한 접근을 제공한다.
- 반면에 ApplicationRunner는 9번에서 보았던 ApplicationArguments를 사용한다.
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
// Do something...
}
}
- 여러 CommandLineRunner or ApplicationRunner 빈들이 순차적으로 실행되야 한다면 org.springframework.core.Ordered 인터페이스 또는 org.springframework.core.annotation.Order 어노테이션을 사용하면 된다.
11. Application Exit
- SpringApplication은 종료 시 ApplicationContext가 정상적으로 닫히도록 JVM에 종료 훅을 등록한다.
그래서 모든 Spring은 lifecycle callback을 사용할 수 있다.
(DisposableBean인터페이스 or @PreDestroy) - SpringApplication.exit() 이 불려진 후에 bean들이 구체적인 exit code를 반환하고 싶다면 org.springframework.boot.ExitCodeGenerator 인터페이스를 구현하면 된다.
exit code는 System.exit()으로 전달될 수 있다.
@SpringBootApplication
public class MyApplication {
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args)));
}
}
- ExitCodeGenerator 인터페이스는 예외로 구현될 수 있다.
어떤 예외가 발생했을 때 Spring Boot가 getExit() 메서드로 구현된 exitcode를 반환한다. - ExitCodeGenerator가 여러개라면 0이 아닌 첫번째 exit 코드가 사용된다.
- generator들의 순서를 정하기 위해서 org.springframework.core.Ordered 인터페이스 또는 org.springframework.core.annotation.Order 어노테이션을 사용하면 된다.
12. Admin Features
- spring.application.admin.enabled 속성으로 admin 기능들을 사용할 수 있다.
- 이것은 SpringApplicationAdminMXBean을 MBeanServer에 노출시킨다.
- 이 기능은 Spring Boot application을 원격으로 관리하는데 유용하다.
13. Application Startup tracking
- application 시작 시, SpringApplication 과 ApplicationContext는
application lifecycle, bean lifecycle, processing application event와 관련된 많은 일을 수행한다. - ApplicationStartup을 세팅하여 시간 과정을 추적할 수 있다.
예를들어 BufferingApplicationStartup을 사용할 수 있다..
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(MyApplication.class);
application.setApplicationStartup(new BufferingApplicationStartup(2048));
application.run(args);
}
}
- BufferingApplicationStartup은 시작과정을 저장하고 외부에 데이터를 제공할 수 있다.
모든 컴포넌트에서 BufferingApplicationStartup 빈을 요청할 수 있다. - 그 외 FlightRecorderApplicationStartup 등의 구현체도 있다.
- JSON 으로 정보를 제공하는 startup endpoint를 만드는 방법은 아래 참고
Spring Boot Actuator Web API Documentation
728x90
'Back-End > Spring' 카테고리의 다른 글
[Spring] pet clinic - rest api (0) | 2023.05.02 |
---|---|
[Spring] pet clinic - 스프링 대표 예제 프로젝트 (0) | 2023.04.08 |
[Spring Boot] Spring Boot - Web(Servelet Web Applications) (0) | 2023.03.30 |
[Spring Boot] 스프링 부트 사용하기 (0) | 2023.03.30 |
MVC 컨트롤러 List로 받기 (0) | 2021.03.14 |
댓글