main() 메소드로 시작하는 스프링 애플리케이션은 SpringApplication 클래스로 간단하게 부트스트랩할 수 있다. 대부분은 다음 예제처럼 스태틱 메소드 SpringApplication.run에 부트스트랩을 위임하면 된다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
애플리케이션을 시작하면 다음과 유사한 문구가 출력되는 것이 보일 것이다.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: v2.5.2
2021-02-03 10:33:25.224 INFO 17321 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : Starting SpringAppplicationExample using Java 1.8.0_232 on mycomputer with PID 17321 (/apps/myjar.jar started by pwebb)
2021-02-03 10:33:25.226 INFO 17900 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : No active profile set, falling back to default profiles: default
2021-02-03 10:33:26.046 INFO 17321 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-02-03 10:33:26.054 INFO 17900 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-02-03 10:33:26.055 INFO 17900 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-02-03 10:33:26.097 INFO 17900 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-02-03 10:33:26.097 INFO 17900 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 821 ms
2021-02-03 10:33:26.144 INFO 17900 --- [ main] s.tomcat.SampleTomcatApplication : ServletContext initialized
2021-02-03 10:33:26.376 INFO 17900 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2021-02-03 10:33:26.384 INFO 17900 --- [ main] o.s.b.d.s.s.SpringAppplicationExample : Started SampleTomcatApplication in 1.514 seconds (JVM running for 1.823)
기본적으로 애플리케이션을 시작한 사용자 등 상세한 기동 정보를 가지고 있는 INFO 로그 메시지가 출력된다. INFO 말고 다른 로그 레벨을 원한다면 로그 레벨에서 설명하는 대로 설정을 넣으면 된다. 기동 정보 로깅은 spring.main.log-startup-info
를 false로 설정하면 끌 수 있다. 이렇게 하면 애플리케이션의 활성 프로파일 로깅도 꺼진다. 기동 시에 부가적인 로그를 넣고 싶다면 SpringApplication의 하위 클래스에서 logStartupInfo(boolean)
을 재정의하면 된다.
애플리케이션 기동에 실패했다면 등록돼 있는 FailureAnalyzers가 전용 에러 메시지와 문제 해결을 위해 필요한 구체적인 조치를 알려줄 것이다. 예를 들어 8080 포트가 이미 사용 중이라면 아래 메시지와 유사한 내용을 볼 수 있을 것이다.
***************************
APPLICATION FAILED TO START
***************************
Description:
Embedded servlet container failed to start. Port 8080 was already in use.
Action:
Identify and stop the process that's listening on port 8080 or configure this application to listen on another port.
예외를 처리할 수 있는 failure analyzer가 없더라도 전체 컨디션 리포트를 표기하면 무엇이 잘못됐는지를 파악하기가 좀 더 쉬워진다. 컨디션 리포트를 출력하려면 debug 프로퍼티를 활성화 하면 된다. 예를 들어 java –jar
를 사용해서 애플리케이션을 실행한다면 다음과 같이 debug 프로퍼티를 활성화할 수 있다.
$ java -jar myproject-0.0.1-SNAPSHOT.jar —debug
SpringApplication은 필요에 따라 애플리케이션을 지연 방식으로 초기화할 수 있다. 지연된 초기화가 활성화되면 애플리케이션을 기동하면서 필요에 따라 빈을 만든다. 잘못 설정한 빈을 지연 방식으로 초기화하게 되면 기동 시엔 실패하지 않으며 해당 빈을 초기화할 때가 돼서야 문제가 드러난다. 이러한 이유로 지연 초기화는 기본적으로 활성화하지 않는다.
지연 초기화는 spring.main.lazy-initialization
프로퍼티로 활성화해도 된다.
spring.main.lazy-initialization=true
spring:
main:
lazy-initialization: true
기동 시 출력하는 배너는 클래스패스에 banner.txt
파일을 추가하거나 spring.banner.location
프로퍼티를 배너 파일의 위치로 설정해서 변경할 수 있다. 텍스트 파일 외에도 banner.gif
, banner.jpg
, banner.png
같은 이미지 파일도 클래스패스에 추가하거나 spring.banner.image.location
프로퍼티에 설정할 수 있다. 이미지는 ASCII 아트로 변환되며 텍스트 배너 위에 출력된다.
banner.txt
파일 안에서는 다음과 같은 플레이스 홀더를 사용할 수 있다.
${application.version}
: Maven이나 Gradle을 사용하여 애플리케이션 버전을 설정한 경우 그 값을 출력한다.${application.formatted-version}
: 버전 번호 앞에 'v'가 붙은 형태로 출력한다. 예를 들어, v1.0.0.${spring-boot.version}
: 사용 중인 스프링 부트의 버전을 출력한다.${spring-boot.formatted-version}
: 스프링 부트 버전 번호 앞에 'v'가 붙은 형태로 출력한다.${Ansi.NAME}
: 이름에 해당하는 ANSI 색상 코드를 삽입한다. NAME은 'BLACK', 'RED', 'GREEN', 'YELLOW', 'BLUE', 'MAGENTA', 'CYAN', 'WHITE' 중 하나가 될 수 있다.${application.title}
: 애플리케이션의 제목을 출력한다. 애플리케이션 제목은 SpringApplication.setApplicationName() 메서드를 사용하여 설정할 수 있다.SpringApplication 기본 값이 마음에 들지 않으면 로컬 인스턴스를 만들어 커스텀해도 된다.
ApplicationContext를 계층구조로 만들어야 하거나 fluent 빌더 API를 선호한다면 SpringApplicationBuilder를 사용하면 된다.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
}
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(MyApplication.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
}
}
SpringApplication이 시작되고 나서 실행해야 하는 코드가 있다면 ApplicationRunner나 CommandLineRunner 인터페이스를 구현하면 된다. 이 인터페이스는 애플리케이션을 기동한 후 트래픽을 받기 시작하기 전에 실행해야 하는 작업에 적합하다.
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("Application started with CommandLineRunner");
}
}
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.boot.ApplicationArguments;
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("Application started with ApplicationRunner");
}
}
모든 SpringApplication은 JVM에 셧다운 훅을 등록해서 종료 시 ApplicationContext가 정상적으로 닫히도록 만든다. 또한 SpringApplication.exit()를 호출할 때 특정 종료 코드를 반환하고 싶은 빈은 org.springframework.boot.ExitCodeGenerator 인터페이스를 구현하면 된다.
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.stereotype.Component;
@Component
public class MyExitCodeGenerator implements ExitCodeGenerator {
@Override
public int getExitCode() {
// return the desired exit code
return 42;
}
}
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyApplication.class, args)));
}
}