[SpringBoot] SpringApplication 인 스 턴 스 생 성
책 은 지난 번 에 Spring Boot 가 작 동 하 는 입 구 는
JarLauncher
의 main
방법 이 라 고 말 했다.그 중의 주요 논 리 는 각종 자원 을 불 러 온 후에 새로운 스 레 드 호출 프로그램의 입 구 를 여 는 것 이다.전체 응용 프로그램의 시작 은 여기 서 천천히 전개 되 고 본 고 는 SpringApplication
의 정적 방법 run
에서 호출 된 후에 SpringApplication
인 스 턴 스 를 생 성 하 는 과정 만 설명 한다.그 후의 다른 시작 절 차 는 본 논문 에 기록 되 어 있 지 않다.앞에서 말 한
main
방법의 호출:@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
정적
run
방법 은 전체 프로그램의 입구 이지 만 최종 적 으로 예화 되 었 다 SpringApplication
대상: private final Set
오늘 의 목 표 는
initialize
방법의 실현 이다. private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
this.sources.addAll(Arrays.asList(sources));
}
// web
this.webEnvironment = deduceWebEnvironment();
//
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// main
this.mainApplicationClass = deduceMainApplicationClass();
}
웹 환경 추정
먼저 웹 환경의 판단 을 살 펴 보 자.
// org/springframework/boot/SpringApplication.java
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
"org.springframework.web.context.ConfigurableWebApplicationContext" };
private boolean deduceWebEnvironment() {
for (String className : WEB_ENVIRONMENT_CLASSES) {
if (!ClassUtils.isPresent(className, null)) {
return false;
}
}
return true;
}
주어진 클래스 로 더 (null) 가 주어진 클래스
WEB_ENVIRONMENT_CLASSES
를 불 러 올 수 있 는 지 판단 합 니 다.로 더 는 비어 있 습 니 다. 따라 들 어가 면 비어 있 을 때 기본 클래스 로 더 가 있 습 니 다. // org/springframework/util/ClassUtils.java
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
try {
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
}
if (cl == null) {
cl = ClassUtils.class.getClassLoader();
if (cl == null) {
try {
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
}
}
}
return cl;
}
메 인 방법 찾기
다른 방법 을 건 너 뛰 고 먼저 보기
main
방법 이 있 는 클래스 찾기 private Class> deduceMainApplicationClass() {
try {
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) {
// Swallow and continue
}
return null;
}
이
main
방법 이 있 는 종 류 를 찾 는 것 은 6 을 비교 하 는 것 입 니 다. 직접 이상 을 만들어 서 창고 에서 찾 는 것 도 기이 한 기교가 라 고 할 수 있 습 니 다.초기 화 장치, 모니터 의 로드, 예화
다음은
SpringApplication
실례 화의 가장 중요 한 부분 인 초기 화기 와 감청 기의 설정 을 중점적으로 살 펴 보 자.이들 의 핵심 논 리 는 모두 같 지만 매개 변수 가 다 를 뿐이다.
private Collection extends T> getSpringFactoriesInstances(Class type) {
return getSpringFactoriesInstances(type, new Class>[] {});
}
private Collection extends T> getSpringFactoriesInstances(Class type,
Class>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
// ,
Set names = new LinkedHashSet(
SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// ,
List instances = createSpringFactoriesInstances(type, parameterTypes,
classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
//
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
// key factoryClass.getName()
public static List loadFactoryNames(Class> factoryClass,
ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
try {
Enumeration urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
List result = new ArrayList();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties =
PropertiesLoaderUtils.loadProperties(new UrlResource(url));
String factoryClassNames =
properties.getProperty(factoryClassName);
result.addAll(Arrays.asList(
StringUtils.commaDelimitedListToStringArray(factoryClassNames)));
}
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +
"] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
모든 초기 화 장치 와 모니터 는 CLASSPATH 의
META-INF/spring.factories
파일 에서 가 져 옵 니 다. 구체 적 인 설정:# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener
SpringApplication 의 인 스 턴 스 과정 을 요약 합 니 다.
META-INF/spring.factories
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.