스프링 프로젝트 시작 상세 과정(소결)
본문 은 통용 되 는 Tomcat 를 예 로 들 었 다.
2.프로젝트 용기 가 시 작 될 때 읽 기 웹.xml 프로필 을 불 러 와 야 합 니 다.
다음 그림:
3.용 기 는 먼저 웹.xml 프로필 의 두 노드 를 읽 습 니 다.
설명:
tomcat 는 웹 용 기 를 시작 할 때 ServletContextListener 라 는 감청 기 를 시작 합 니 다.웹 용기 에 ServletContextListener 라 는 인터페이스 가 실례 화 될 때마다 웹 용 기 는 ServletContextListener 가 실례 된 대상 에 게 context Initialized()를 실행 하 는 방법 을 알려 줍 니 다.
한편,spring 프레임 워 크 는 디자인 과정 에서 ContextLoadListener 라 는 종 류 는 ServletContextListener 라 는 인 터 페 이 스 를 실현 하기 때문에 ContextLoadListener 라 는 종 류 를 예화 할 때마다 웹 용 기 는 Spring 에 contextInitialized()라 는 방법 을 실행 하 라 고 알 리 고 spring 용기 의 시작 과 생 성 과정 에 들 어 갑 니 다.
4.ContextLoaderListener 의 contextInitialized()는 spring 용기 의 시작 설정 을 실 시 했 고 initWebapplicationContext 를 호출 하여 spring 용 기 를 초기 화 합 니 다.
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
//Spring ,spring
if(servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException("Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!");
} else {
Log logger = LogFactory.getLog(ContextLoader.class);
servletContext.log("Initializing Spring root WebApplicationContext");
if(logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis();
try {
// spring ( spring bean)
if(this.context == null) {
this.context = this.createWebApplicationContext(servletContext);
}
if(this.context instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
if(!cwac.isActive()) {
if(cwac.getParent() == null) {
ApplicationContext parent = this.loadParentContext(servletContext);
cwac.setParent(parent);
}
//Spring , spring
this.configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if(ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
} else if(ccl != null) {
currentContextPerThread.put(ccl, this.context);
}
if(logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if(logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
return this.context;
} catch (RuntimeException var8) {
logger.error("Context initialization failed", var8);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var8);
throw var8;
} catch (Error var9) {
logger.error("Context initialization failed", var9);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, var9);
throw var9;
}
}
}
5.spring 용기 생 성 이 완료 되면 bean 을 정례 화 할 준 비 를 합 니 다.Spring 용기 생 성 이 완료 되면 spring 용기 에 bean 을 불 러 올 준 비 를 합 니 다.configureAndrRefreshWebapplicationContext(cwac,servletContext)를 사용 합 니 다.bean 로드 완료 하기;
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
// The application context id is still set to its original default value
// -> assign a more useful id based on available information
String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
if (idParam != null) {
wac.setId(idParam);
}
else {
// Generate default id...
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
wac.setServletContext(sc);
String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocationParam != null) {
wac.setConfigLocation(configLocationParam);
}
// The wac environment's #initPropertySources will be called in any case when the context
// is refreshed; do it eagerly here to ensure servlet property sources are in place for
// use in any post-processing or initialization that occurs below prior to #refresh
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
}
customizeContext(sc, wac);
wac.refresh();
}
설명:configureAndRefreshWebapplicationContext 에서 spring 의 프로필 을 불 러 옵 니 다.즉,웹.xml 에서
혹시
다음 코드 를 통 해 spring 설정 을 불 러 옵 니 다.
public class Application{
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/context.xml");
ctx.start();
}
}
기본 리 소스 로 더 를 어떻게 호출 하 는 지 생략 합 니 다.최상 위 인터페이스 ResourceLoader 는 하나의 getResource(String location)방법 만 제공 합 니 다.자원 주소 에 따라 자원 파일 을 불 러 올 수 있 습 니 다.자원 주소 표현 식 은 다음 과 같 습 니 다.
--1.classpath:접두사 로 시작 하 는 표현 식,예 를 들 어 classpath:smart-context.xml
--2."/"로 시작 하 는 표현 식,예 를 들 어/WEB-INF/classes/smart-context.xml
--3."/"로 시작 하지 않 는 표현,예 를 들 어 WEB-INF/classes/smart-context.xml
--4.url 프로 토 콜,예:file:/D:/ANWANG-AIA/Horse-workspace/chapter 3/target/classes/smart-content.xml
Spring 은 구현 클래스 DefaultResourceLoader 를 제공 합 니 다.DefaultResourceLoader 는 상기 열거 한 기능 을 바탕 으로 개발 자 에 게 사용자 정의 확장 인터페이스 ProtocolResolver 를 제공 합 니 다.개발 자 는 이 인터페이스의 맞 춤 형 자원 표현 식 을 실현 할 수 있 습 니 다.코드 는 다음 과 같 습 니 다.
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
for (ProtocolResolver protocolResolver : this.protocolResolvers) { // 1
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {return resource;}
}
if (location.startsWith("/")) {return getResourceByPath(location);} //2
else if (location.startsWith(CLASSPATH_URL_PREFIX)) { //3
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
// Try to parse the location as a URL...
URL url = new URL(location); //4
return new UrlResource(url);
}
catch (MalformedURLException ex) {
// No URL -> resolve as resource path.
return getResourceByPath(location); //5
}
}
}
단계 1,우선 확장 프로 토 콜 해상도 기로 자원 주 소 를 분석 하고 되 돌려 줍 니 다.예 를 들 어 접두사'classpath:'의 해석 을 위해 자원 해석 기 를 사용자 정의 할 수 있 습 니 다.우선 ProtocolResolver 인터페이스 구현:
class ClasspathPreProtocolResolver implements ProtocolResolver{
private static String CLASS_PATH_PRE="classpath:";
public Resource resolve(String location, ResourceLoader resourceLoader) {
if( location.startsWith(CLASS_PATH_PRE)) {
return new ClassPathResource(location.substring(CLASS_PATH_PRE.length()));
}
return null;
}
}
단계 2.location 이 슬 래 쉬 로 시작한다 고 가정 하면 이 클래스 의 getResourceByPath(String path)방법 을 호출 합 니 다.코드 는 다음 과 같 습 니 다.
protected Resource getResourceByPath(String path) {
return new ClassPathContextResource(path, getClassLoader());
}
절차 3.자원 표현 식 이 classpath 로 시작 하면 접두사 calsspath:의 경 로 를 차단 하고 ClassPathResource 의 구조 적 매개 변수 로 서 ClassPathResource 인 스 턴 스 를 생 성 한 후 돌아 갑 니 다.우 리 는 웹.xml 에서 다음 과 같은 설정 을 할 수 있 습 니 다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/config/applicationContext.xml</param-value>
</context-param>
6refresh()
내부 의 실현 을 통 해 우 리 는 대체적으로 전체refresh()
방법 은 전체 Spring 용기 의 초기 화 와 로드 의 모든 논 리 를 맡 았 다.이 는 Bean 공장 의 초기 화,post-processor 의 등록 과 호출,bean 의 정례 화,사건 발표 등 을 포함한다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.