Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ๋ ์ฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ๋จผ์ ๋ง์ฃผํ๋ ์ฝ๋๋ @SpringBootApplication ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค์ ๊ทธ ์์ main ๋ฉ์๋์ผ ๊ฒ์ด๋ค.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}Java๋ช ์ค ์๋๋ ๋งค์ฐ ๊ฐ๋จํ ์ฝ๋์ง๋ง SpringApplication.run() ํธ์ถ ๋ค์๋ ์์ญ ๊ฐ์ ํด๋์ค๊ฐ ํ๋ ฅํ์ฌ ๋ณต์กํ ์ด๊ธฐํ ๊ณผ์ ์ ์ํํ๋ค. Spring Boot๋ ์ด๋ฌํ ๋ณต์ก์ฑ์ ์จ๊ธฐ๊ณ ๊ฐ๋ฐ์์๊ฒ ๋จ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ์ง๋ง ๋ด๋ถ ๋์์ ์ดํด ํ๋ฉด ๋ ํจ๊ณผ์ ์ผ๋ก Spring Boot๋ฅผ ํ์ฉํ ์ ์๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ SpringApplication ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ๋ด๋ถ์ ์ผ๋ก ์ด๋ค ๋์๋ค์ด ์ด๋ฃจ์ด์ง๋์ง ์ ๋ฆฌํด ๋ณด๊ณ ์ ํ๋ค.
SpringApplication์ ์ญํ
SpringApplication ํด๋์ค๋ Spring Boot ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ถํธ์คํธ๋ํ์ ๋ด๋นํ๋ ํต์ฌ ํด๋์ค๋ค. ์ด ํด๋์ค๋ ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํ๋ ๊ฒ์ ๋์ด์ ์ ์ ํ ApplicationContext๋ฅผ ์์ฑํ๊ณ ํ๊ฒฝ์ ๊ตฌ์ฑํ๊ณ ๋ค์ํ ๋ฆฌ์ค๋๋ค์ ๊ด๋ฆฌํ๋ ์ญํ ์ ์ํํ๋ค.
SpringApplication ์ธ์คํด์ค๊ฐ ์์ฑ๋ ๋ ์ํ๋๋ ์ด๊ธฐํ ์์
์ ์ดํด๋ณด์.
SpringApplication.run(MyApplication.class, args); ์ฝ๋๊ฐ ์คํ๋๋ฉด ๋ด๋ถ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ํ๋ฆ์ผ๋ก ์ฝ๋๊ฐ ์คํ๋๋ค.
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
// SpringApplication.run() ์คํ์ ํธ์ถ๋๋ ์์ฑ์
public SpringApplication(Class<?>... primarySources) {
this(null, primarySources);
}
// SpringApplication.run() ์คํ์ ์ต์ข
์ ์ผ๋ก ํธ์ถ๋๋ ์์ฑ์
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// resourceLoader ์ธ์คํด์ค ์ค์
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// ๋ฉ์ธ ํด๋์ค ์ค์
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// classPath๋ฅผ ํตํ WebApplicationType ์๋ ๊ฐ์ง
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// BootstrapRegistryInitializer ํด๋์ค ๋ก๋ฉ
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// ApplicationContextInitializer ํด๋์ค ๋ก๋ฉ
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// ApplicationListener ํด๋์ค ๋ก๋ฉ
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}JavaSpringApplication.run() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉด ๋ด๋ถ์ ์ผ๋ก new SpringApplication(..)์ ํตํด์ ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
์ด ๋ ์์ฑ์์์๋ ๋ค์๊ณผ ๊ฐ์ ํต์ฌ ์ด๊ธฐํ ์์
์ ์ํํ๋ค.
- ResourceLoader๋ฐ ๊ธฐ๋ณธ ์์ค ์ค์
- ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฌ์ฉํ ๋ฆฌ์์ค๋ฅผ ์ฝ์ด์ฌ ๋ก๋๋ฅผ ์ค์ ํ๊ณ @SpringBootApplication์ด ์ ์ธ๋ ๋ฉ์ธ ํด๋์ค๋ฅผ ์ ์ฅํ์ฌ ์ด ํ ๋น ์ค์บ๋์ ๊ธฐ์ ์ผ๋ก ์ผ๋๋ค.
- ๊ธฐ๋ณธ์ ์ผ๋ก SpringApplication.run(…)์ ํธ์ถํ ๊ฒฝ์ฐ์๋ ResourceLoader๋ null์ด ์ ๋ฌ๋๋ค. ํ์ ๋ด๋ถ์ ์ผ๋ก DefaultResourceLoader๋ฅผ ์์ฑํ์ฌ ์ฌ์ฉํ๋ค.
- WebApplicationType ์๋ ๊ฐ์ง
- Spring Boot์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ์๋ ์ค์ ์ด๋ค. ๊ฐ๋ฐ์๊ฐ ๋ณ๋์ ์ค์ ์ ํ์ง ์์๋ Spring Boot๋ sspath๋ฅผ ๋ถ์ํด ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ ํ์
์ ๊ฒฐ์ ํ๋ค.
- SERVLET: DispatcherServlet ํด๋์ค๊ฐ ํด๋์คํจ์ค์ ์๋ค๋ฉด ์ผ๋ฐ์ ์ธ Spring MVC ์น ์ฑ์ผ๋ก ๊ตฌ๋ํ๋ค.
- REACTIVE: DispatcherHandler๊ฐ ์๊ณ ์๋ธ๋ฆฟ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋ค๋ฉด WebFlux ๊ธฐ๋ฐ์ ๋ฆฌ์กํฐ๋ธ ์ฑ์ผ๋ก ๊ตฌ๋ํ๋ค.
- NONE: ์ ํด๋์ค๋ค์ด ์๋ค๋ฉด ์น ์๋ฒ๊ฐ ํ์์๋ ์ผ๋ฐ ์๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ๊ตฌ๋๋๋ค.
- Spring Boot์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ ์๋ ์ค์ ์ด๋ค. ๊ฐ๋ฐ์๊ฐ ๋ณ๋์ ์ค์ ์ ํ์ง ์์๋ Spring Boot๋ sspath๋ฅผ ๋ถ์ํด ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ ํ์
์ ๊ฒฐ์ ํ๋ค.
- ์ด๊ธฐํ ๊ด๋ จ ์ปดํฌ๋ํธ ๋ก๋
- BootstrapRegistryInitializer
- META-INF/spring.factories ์์ BootstrapRegistryInitializer ํ์ ์ ๊ตฌํ์ฒด๋ค์ ์ฐพ์์ ๋ก๋ฉํ๋ค. ํด๋น ๊ตฌํ์ฒด๋ค์ ๋ถํธ์คํธ๋ฉ ๋ ์ง์คํธ๋ฆฌ ์ด๊ธฐํ๋ฅผ ์ํ ์ปดํฌ๋ํธ๋ค์ด๋ค.
- ApplicationContextInitializer
- META-INF/spring.factories ์์ ApplicationContextInitializer ํ์ ์ ๊ตฌํ์ฒด๋ค์ ์ฐพ์์ ๋ก๋ฉํ๋ค. ํด๋น ๊ตฌํ์ฒด๋ค์ ApplicationContext ์ด๊ธฐํ๋ฅผ ์ํ ์ปดํฌ๋ํธ๋ค์ ๋ก๋ํ๋ค.
- ApplicationListener
- META-INF/spring.factories ์์ ApplicationListener ํ์ ์ ๊ตฌํ์ฒด๋ค์ ์ฐพ์์ ๋ก๋ฉํ๋ค. ํด๋น ๊ตฌํ์ฒด๋ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ฒคํธ๋ฅผ ์์ ํ ๋ฆฌ์ค๋ ์ญํ ์ ํ๋ค.
- BootstrapRegistryInitializer
๋ค์์ spring boot 3.2.1 ๋ฒ์ ์ spring-boot-auto-configure์ spring.factories ํ์ผ์ ์ผ๋ถ๋ค.
# ApplicationContext Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializerJavaWebApplicationType ์๋ ๊ฐ์ง ๋ฉ์นด๋์ฆ ๋๋ถ์ spring-boot-starter-web ์์กด์ฑ๋ง ์ถ๊ฐํด๋ ์๋์ผ๋ก ๋ด์ฅ๋ ํฐ์บฃ์ ํตํด ์น ์๋ฒ๊ฐ ์คํ๋๋ค.
META-INF/spring.factories ํ์ผ์ ์ ํ๋ฆฌ์ผ์ด์ ์์กด์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ํ์ผ์ ์ฐพ๋๋ค.
WebApplicationType ์๋ ๊ฐ์ง
์์ ์ธ๊ธํ๋ฏ์ด Spring Boot๋ ํด๋์คํจ์ค์ ์กด์ฌํ๋ ํด๋์ค๋ค์ ๋ถ์ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
ํ์
์ ์๋์ผ๋ก ๊ฒฐ์ ํ๋ค.
์๋ ๊ฐ์ง๋ฅผ ์ํํ๋ ์ฝ๋๋ฅผ ์ดํด๋ณด์.
// WebApplicationType ํด๋์ค ๋ด๋ถ์ ์์๋ค
// Servlet ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ํ๋ณํ๊ธฐ ์ํ ์ต์ ์กฐ๊ฑด
// ๋ ์ค์ ํ๋๋ผ๋ ์์ผ๋ฉด SERVLET ์น์ด ์๋
private static final String[] SERVLET_INDICATOR_CLASSES = {
"javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext"
};
// Spring MVC(WebMVC) ์กด์ฌ ์ฌ๋ถ ํ๋ณ ํด๋์ค
private static final String WEBMVC_INDICATOR_CLASS =
"org.springframework.web.servlet.DispatcherServlet";
// Spring WebFlux(๋ฆฌ์กํฐ๋ธ ์น) ์กด์ฌ ์ฌ๋ถ
private static final String WEBFLUX_INDICATOR_CLASS =
"org.springframework.web.reactive.DispatcherHandler";
// Jersey(JAX-RS) ๊ธฐ๋ฐ Servlet ์กด์ฌ ์ฌ๋ถ
private static final String JERSEY_INDICATOR_CLASS =
"org.glassfish.jersey.servlet.ServletContainer";
static WebApplicationType deduceFromClasspath() {
// Reactive ํ๋ณ, WebFlux ๋จ๋
์ธ ๊ฒฝ์ฐ์๋ง REACTIVE
// WebFlux๋ Servlet ๊ธฐ๋ฐ๊ณผ ๋์์ ์กด์ฌํ ์ ์์ (๊ธฐ๋ณธ์ Servlet)
if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null)
&& !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) {
return WebApplicationType.REACTIVE;
}
for (String className : SERVLET_INDICATOR_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return WebApplicationType.NONE;
}
}
return WebApplicationType.SERVLET;
}Java์ ์ฝ๋๋ ํด๋์คํจ์ค์ ์ด๋ค ์น ๊ธฐ์ ์ด ์กด์ฌํ๋์ง๋ก ํ์
์ ํ๋จํ๋ค.
WebFlux(๋ฆฌ์กํฐ๋ธ์น)์ ๊ฒฝ์ฐ Servlet๊ณผ ๋์์ ์กด์ฌํ ์ ์๋๋ฐ ๋์์ ์กด์ฌํ๋ ๊ฒฝ์ฐ ํ์
์ SERVLET๊ฐ ๋๋ค.
- SERVLET: ์ ํต์ ์ธ ์๋ธ๋ฆฟ ๊ธฐ๋ฐ ์น ์ ํ๋ฆฌ์ผ์ด์
- spring-boot-starter-web ์์กด์ฑ์ด ์์ ๋
- DispatcherServlet ๊ธฐ๋ฐ
- REACTIVE: ๋ฆฌ์กํฐ๋ธ ์น ์ ํ๋ฆฌ์ผ์ด์
- spring-boot-starter-webflux ์์กด์ฑ์ด ์์ ๋
- Spring WebFlux ๊ธฐ๋ฐ
- NONE: ์น์ด ์๋ ์ผ๋ฐ ์ ํ๋ฆฌ์ผ์ด์
- ์น ๊ด๋ จ ์์กด์ฑ์ด ์์ ๋
- ๋ฐฐ์น ์ ํ๋ฆฌ์ผ์ด์ , CLI ์ ํ๋ฆฌ์ผ์ด์ ๋ฑ
ApplicationContextInitializer์ ApplicationListener ๋ฑ๋ก
Spring Boot๋ META-INF/spring.factories ํ์ผ์ ํตํด ๋ค์ํ ์ด๊ธฐํ ์ปดํฌ๋ํธ๋ค์ ์๋์ผ๋ก ๋ฑ๋กํ๋ค.
private <T> List<T> getSpringFactoriesInstances(Class<T> type) {
return getSpringFactoriesInstances(type, null);
}
private <T> List<T> getSpringFactoriesInstances(Class<T> type, ArgumentResolver argumentResolver) {
return SpringFactoriesLoader.forDefaultResourceLocation(getClassLoader()).load(type, argumentResolver);
}JavaSpring Boot 3.X์ SpringFactoriesLoader ๋ณํ
Spring Boot 3.X์์๋ SpringFactoriesLoader์ ์ฌ์ฉ ๋ฐฉ์์ด ๊ฐ์ ๋์๋ค.
- ๊ธฐ์กด ๋ฐฉ์(2.X): SpringFactoriesLoader.loadFactoryNames() + ์๋ ์ธ์คํด์ค ์์ฑ
- ์๋ก์ด ๋ฐฉ์(3.X): SpringFactoriesLoader.forDefaultResourceLocation().load() ์ง์ ํธ์ถ
์ฃผ์ ๊ฐ์ ์ฌํญ
- fluent API ์คํ์ผ: forDefaultResourceLocation(classLoader).load(type, argumentResolver) ํํ๋ก ๋ฉ์๋ ์ฒด์ด๋์ ์ฌ์ฉํ๋ค.
- ArgumentResolver ์ง์: ์์ฑ์ ํ๋ผ๋ฏธํฐ ํด๊ฒฐ์ ์ํ ArgumentResolver ์ถ๊ฐ ์ง์ํ๋ค.
- ํ์ ์์ ์ฑ ๊ฐํ: ์ ๋ค๋ฆญ์ ํตํ ์ปดํ์ผ ํ์ ํ์ ์ฒดํฌ
- ์ฑ๋ฅ ์ต์ ํ: ๋ด๋ถ์ ์ผ๋ก ์บ์ฑ๊ณผ ์ธ์คํด์ค ์์ฑ ๊ณผ์ ์ด ์ต์ ํ ๋์๋ค.
ApplicationContextInitializer์ ์ญํ
- ApplicationContext๊ฐ refresh ๋๊ธฐ ์ ์ ์ถ๊ฐ์ ์ธ ์ด๊ธฐํ ์์ ์ํ
- PropertySource ์ถ๊ฐ, ํ๋กํ์ผ ํ์ฑํ, Bean ์ ์ ํ์ฒ๋ฆฌ ๋ฑ
- ์: ConfigurationWarningsApplicationContextInitializer, ContextIdApplicationContextInitializer
ApplicationListener์ ์ญํ
- ์ ํ๋ฆฌ์ผ์ด์ ์์ ๊ณผ์ ์ ๋ค์ํ ์ด๋ฒคํธ๋ฅผ ์์ ํ์ฌ ๋ก๊น , ๋ชจ๋ํฐ๋ง, ์ปค์คํ ์ด๊ธฐํ ๋ก์ง ์คํ
- ์: LoggingApplicationListener, BackgroundPreinitializer, DelegatingApplicationListener
BootstrapRegistryInitializer์ ์ญํ
- ApplicationContext ์์ฑ ์ด์ ๋จ๊ณ์์ ํ์ํ ์๋น์ค๋ค์ BootstrapRegistry์ ๋ฑ๋ก
- ์ด๊ธฐ ์ค์ ์ด๋ ์ธ๋ถ ์์คํ ์ฐ๊ฒฐ๋ฑ ๋ถํธ์คํธ๋ฉ ๋จ๊ณ์์ ํ์ํ ์์ ์ํ
SpringApplication ์ฃผ์ public ๋ฉ์๋
SpringApplication.run() ์ ์ ๋ฉ์๋ ํธ์ถ๋ก ๊ธฐ๋ณธ์ ์ธ ์ ํ ์ ํ ์ ์์ง๋ง SpringApplication ์ธ์คํด์ค๋ฅผ ์ง์ ์์ฑํ์ฌ ๋ค์ํ public ๋ฉ์๋๋ฅผ ํตํด ๊ตฌ๋ ํ๊ฒฝ์ ์ธ๋ฐํ๊ฒ ์กฐ์ ํ ์ ์๋ค.
| ๋ฉ์๋ | ์ค๋ช | ๋ํดํธ |
| setWebApplicationType | Classpath ๊ธฐ๋ฐ์ ์๋ ๊ฐ์ง ๋์ ์ ํ๋ฆฌ์ผ์ด์ ํ์ ์ ๊ฐ์ ๋ก ์ง์ ํ๋ค. (SERVLET, REACTIVE, NONE) | ์๋๊ฐ์ง |
| setBannerMode | ์์์ ์ถ๋ ฅ๋๋ ๋ฐฐ๋์ ํํ๋ฅผ ์ค์ ํ๋ค. (CONSOLE, LOG, OFF) | CONSOLE |
| setAdditionalProfiles | ์ฝ๋ ๋ ๋ฒจ์์ ํ์ฑํํ ํ๋กํ์ผ์ ์ถ๊ฐํ๋ค. | ์์ |
| setLazyInitialization | ๋น(Bean)๋ค์ ํ์ํ ์์ ์ ์์ฑํ๋๋ก ์ง์ฐ ์ด๊ธฐํ ์ฌ๋ถ๋ฅผ ์ค์ ํ๋ค. | false |
| addListeners | ํน์ ๊ตฌ๋ ๋จ๊ณ์์ ๋์ํ ์ปค์คํ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํ๋ค. | |
| run(String… args) | ์ค์ ์ ๋ง์น ํ ์ค์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ๋ํ๋ ํต์ฌ ๋ฉ์๋๋ค. | |
| setRegisterShutdownHook | JVM ์ข ๋ฃ์ Spring ์ปจํ ์คํธ๊ฐ ์์ ํ๊ฒ ๋ซํ๋๋ก ์ ง๋ค์ด ํ ์ ์๋์ผ๋ก ๋ฑ๋กํ๋ค. | true |
| setLogStartupInfo | ์์์ ๋ฉ์ธํด๋์ค ์ด๋ฆ, ํ๋กํ์ผ ์ ๋ณด, ๊ตฌ๋ ์๊ฐ๋ฑ์ ๋ก๊ทธ๋ก ์ถ๋ ฅํ๋ค. | true |
| setHeadless | ์๋ฒ ํ๊ฒฝ์ ๊ณ ๋ คํ์ฌ java.awt.headless ํ๋กํผํฐ๋ฅผ true๋ก ์๋ ์ค์ ํ๋ค. | true |
| addInitializers(…) | ApplicationContextInitializer๋ฅผ ์ง์ ์ถ๊ฐ ํ๋ค. Customํ๊ฒ ์์ฑํ ApplicaltionContextInitializer๋ฅผ ์์ฝ๊ฒ ์ถ๊ฐํ ์ ์๋ค. |
WebApplicationType ์ง์ ์ง์ ์ด ํ์ํ ๊ฒฝ์ฐ
๋๋ถ๋ถ์ ์๋๊ฐ์ง๋ฅผ ํตํด์ ์ฌ์ฉํ๊ฒ ์ง๋ง ๊ฒฝ์ฐ์ ๋ฐ๋ผ์ ์ง์ ์ง์ ์ด ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋ค.
1. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถฉ๋ ์ํฉ: ํ๋ก์ ํธ์ spring-boot-starter-web๊ณผ spring-boot-starter-webflux๊ฐ ๋์์ ํฌํจ๋์ด ์๋ ๊ฒฝ์ฐ Spring Boot๋ ๊ธฐ๋ณธ์ ์ผ๋ก SERVLET ํ์ ์ ์ฐ์ ํ์ง๋ง WebFlux๋ก ๋๋ฆฌ๊ณ ์ถ๋ค๋ฉด ์ง์ ์ง์ ํด์ผ ํ๋ค.
2. ์น ํ๊ฒฝ ์ ์ธ(Test/Batch): ์น ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ํฌํจ๋์ด ์์ง๋ง ํน์ ์คํ ํ๊ฒฝ(์: ๋ฐ์ดํฐ ๋ง์ด๊ทธ๋ ์ด์ ํด, ๋ก์ปฌ ๋ฐฐ์น ์์ )์์๋ ์๋ฒ๋ฅผ ๋์ฐ๊ณ ์ถ์ง ์์ ๋ WebApplicationType.NONE์ผ๋ก ๊ฐ์ ํ ์ ์๋ค.
3. ํ์ด๋ธ๋ฆฌ๋ ๊ตฌ์ฑ: ํ๋์ ํ๋ก์ธ์ค ๋ด์์ ์น ์๋ฒ๋ฅผ ๋์ฐ๋ ์ปจํ ์คํธ์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์ ์ ์ํํ๋ ๋น์น(NONE) ์ปจํ ์คํธ๋ฅผ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ก ๋ฌถ์ด์ ์คํํ๋ ํน์ํ ๋๊ท๋ชจ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ฑ์ ์ฌ์ฉํ๋ค.
์ฌ์ฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
@SpringBootApplication
public class AdvancedConfigApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(AdvancedConfigApplication.class);
// ์
ง๋ค์ด ํ
ํ์ฑํ (๊ธฐ๋ณธ๊ฐ์ด true์ด์ง๋ง ๋ช
์์ ์ผ๋ก ์ ์ด ๊ฐ๋ฅ)
// ์ปจํ
์คํธ ์ข
๋ฃ ์ ๋ฆฌ์์ค ์ ๋ฆฌ๋ฅผ ๋ณด์ฅํ๋ค.
app.setRegisterShutdownHook(true);
// ์์ ์ ๋ณด ๋ก๊ทธ ์ถ๋ ฅ ๋นํ์ฑํ
// ์์ ์๊ฐ์ด๋ ํ๋กํ์ผ ์ ๋ณด๊ฐ ๋ก๊ทธ์ ๋จ์ง ์๋๋ก ํ๋ค.
app.setLogStartupInfo(false);
// 3. ํค๋๋ฆฌ์ค ๋ชจ๋ ๋นํ์ฑํ
// ๋ง์ฝ ์๋ฒ์์ GUI ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(๊ทธ๋ํ ์์ฑ ๋ฑ)๋ฅผ ์ง์ ์ฌ์ฉํด์ผ ํ๋ค๋ฉด false๋ก ์ค์ ํ๋ค.
app.setHeadless(false);
// ์น ํ๊ฒฝ์ด ํ์ ์๋ ๋ฐฐ์น์ฑ ์ ํ๋ฆฌ์ผ์ด์
์ผ ๊ฒฝ์ฐ ๊ฐ์ ์ง์
app.setWebApplicationType(WebApplicationType.NONE);
// ๋ฐฐ๋๋ฅผ ๋๊ณ ๋ก๊ทธ๋ก๋ง ํ์ธํ๊ณ ์ถ์ ๋
app.setBannerMode(Banner.Mode.OFF);
// ํน์ ํ๋กํ์ผ(์: 'performance')์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ์ถ๊ฐ
app.setAdditionalProfiles("performance");
// ์์ ์๊ฐ ๋จ์ถ์ ์ํด ์ง์ฐ ์ด๊ธฐํ(Lazy Initialization) ํ์ฑํ
app.setLazyInitialization(true);
// ์๋์ผ๋ก ์ด๊ธฐํ ๊ฐ์ฒด ์ถ๊ฐ
// ApplicationContext๊ฐ refresh๋๊ธฐ ์ ์ ํน์ ์ค์ ์ ์ฃผ์
ํฉ๋๋ค.
// app.addInitializers(new MyCustomInitializer());
// ์ ํ๋ฆฌ์ผ์ด์
์ด๋ฆ ์ค์ (Spring Boot 3.x ๊ฐ์์ฑ ํฅ์)
// ๋ก๊ทธ๋ ๋ฉํธ๋ฆญ์์ ์๋ณ์๋ก ์ฌ์ฉ๋ฉ๋๋ค.
// app.setMainApplicationClass(AdvancedConfigApplication.class);
app.run(args);
}
}Java์ง๊ธ๊น์ง SpringApplication ์ธ์คํด์ค๊ฐ ์์ฑ๋ ๋์ ๋์๊ณผ WebApplicationType ์๋๊ฐ์ง๊ฐ ์ด๋ป๊ฒ ์ด๋ฃจ์ด์ง๋์ง ์ดํด๋ดค๋ค.
- ํด๋์คํจ์ค ๊ธฐ๋ฐ์ WebApplicationType ์๋ ๊ฐ์ง
- ๋ชจ๋ ์์กด์ฑ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ META-INF/spring.factories ๋ก๋ถํฐ ์ ํ๋ฆฌ์ผ์ด์
๊ตฌ๋์ ์ํ ์ด๊ธฐํ ํด๋์ค๋ค์ ๋ก๋ฉํ๋ค.
- BootstrapRegistryInitializer ํ์ ํด๋์ค ๋ก๋ฉ
- ApplicationContextInitializer ํ์ ํด๋์ค ๋ก๋ฉ
- ApplicationListener ํ์ ํด๋์ค ๋ก๋ฉ
๋ค์ ํฌ์คํ ์์๋ SpringApplication ์ธ์คํด์ค์ run() ๋ฉ์๋ ๋์์ ์ ๋ฆฌํด๋ณด๋๋ก ํ๊ฒ ๋ค.
๋ค์์ ๋ณด๋ฉด ์ข์ ํฌ์คํ
Spring Boot โ Application Bootstraping์ ์ํ 13๋จ๊ณ
