spring 소스 ------spring 언제 및 언제 웹 응용 프로그램 관련 상하문을 초기화합니까 (FrameworkServlet, DispatcherServlet)
1.
Servlet
사양에서 Spring으로1.1
Servlet
규범 부분 설명spring의 웹 응용(웹-flux 포함하지 않음)은
Servlet
규범을 바탕으로 구축된 것이다. 여기서 먼저 Servlet
규범의 일부 내용을 설명해야 한다. 왜냐하면spring의 웹 상하문의 초기화도 여기서부터 시작되기 때문이다. Servlet
는 엄격하게 정의된 생명주기에 따라 관리된다. 이 생명주기는 Servlet
가 어떻게 불러오는지, 실례화, 초기화, 클라이언트 요청을 처리하는지, 그리고 언제 서비스를 종료하는지를 규정한다.이 성명 주기는 javax.servlet.Servlet
인터페이스의 init
, service
와 destroy
이런 API를 통해 모든Servlet
이 직접적이거나 간접적으로 실현되어야 한다GenericServlet
또는 HttpServlet
추상류를 나타낼 수 있다. servlet
대상을 실례화한 후 용기는 반드시 초기화servlet
한 후에야 클라이언트의 요청을 처리할 수 있습니다.초기화의 목적은 Servlet
가 지속적인 설정 데이터를 읽고 대가가 높은 자원(예를 들어 JDBC™ API
연결을 초기화하거나 일회성 동작을 수행하도록 하는 것이다.용기는 호출Servlet
실례init
방법으로 초기화되었고, init
방법은 Servlet
인터페이스에 정의되어 있으며, 유일한 ServletConfig
인터페이스로 이루어진 대상을 매개 변수로 제공하며, 이 대상은 서브렛 실례마다 하나이다.1.2 초기화된 포털 분석
위의 규범설명에서 알 수 있듯이 스프링은 추상적인
GenericServlet
방법을 실현하고init
관련 정보를 초기화한다. init
방법의 실현류를 보면 스프링의 모든 이 방법의 실현에서 HttpServletBean
만이 수요에 부합된다는 것을 알 수 있다.그래서 우리는 이 방법에 들어갔다.2. 컨텍스트 포털 초기화
HttpServletBean
여기에 직접 들어가서 HttpServletBean
실현된 init
방법을 분석한다. public final void init() throws ServletException {
// Set bean properties from init parameters.
// ServletConfig, servlet ,ServletConfig servlet
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
// ,
if (!pvs.isEmpty()) {
try {
// HttpServletBean BeanWrapper
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
// ServletContext ResourceLoader
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
// ResourceEditor HttpServletBean
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
// ,
initBeanWrapper(bw);
// ServletConfig HttpServletBean
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
if (logger.isErrorEnabled()) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
}
throw ex;
}
}
// , ,
initServletBean();
}
실현된 논리도 비교적 간단함을 알 수 있다.
ServletConfig
에서 servlet 용기에서 초기화된 파라미터를 가져오는 것이다. 속성이 비어 있지 않을 때 자신의 속성 처리 논리를 정의할 수 있고 여기에서 호출된다.용기에 있는 초기화 파라미터를 처리한 후에 초기화를 진행합니다.이 초기화 방법initServletBean
은 하위 클래스에 맡겨 자유롭게 초기화 논리를 실현하는 것이다. 여기 보충 설명ServletConfig
과 ServletContext
두 종류는 모두 servlet
규범 중의 인터페이스 종류이다.여기서 간단하게 설명을 해드릴게요.클래스
설명
ServletConfig
서브렛Config은 웹 응용 프로그램 구성 정보에서 제공하는 키-값 쌍의 초기화 매개변수에 서브렛이 액세스할 수 있도록 하는 각 서브렛 인스턴스 중 하나입니다.
ServletContext
서브렛Context 인터페이스는 서브렛이 실행 중인 웹 응용 프로그램의 보기를 정의합니다. 서브렛은 서브렛Context 대상을 사용하여 이벤트를 기록하고 URL 인용 자원을 가져와 현재 상하문에 있는 다른 서브렛이 접근할 수 있는 속성을 저장할 수 있습니다.기본 서브렛Context는 비분산적이며 하나의 JVM에만 저장됩니다.
3. 웹 응용 상하문 초기화
FrameworkServlet
에서 언급한 initServletBean
방법은 사실 현재 스프링에서 하나의 종류만 실현되었다. 그것이 바로 FrameworkServlet
이다.이 클래스는 스프링이 스프링에 적용되는 상하문에 대한 집적 클래스입니다.역할은 다음과 같습니다.WebApplicationContext
대상을 관리한다.doService
방법을 실현해야 한다.정의 초기화에서 다시 불러올 수도 있습니다. 지금 initFrameworkServlet
에서 어떻게 응용의 초기화를 진행하는지 보고 바로 FrameworkServlet
에 들어가서 보십시오. protected final void initServletBean() throws ServletException {
// ServletContext, servlet
getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
if (logger.isInfoEnabled()) {
logger.info("Initializing Servlet '" + getServletName() + "'");
}
// ,
long startTime = System.currentTimeMillis();
try {
// web WebApplicationContext
this.webApplicationContext = initWebApplicationContext();
// , ,
initFrameworkServlet();
}
catch (ServletException | RuntimeException ex) {
logger.error("Context initialization failed", ex);
throw ex;
}
if (logger.isDebugEnabled()) {
String value = this.enableLoggingRequestDetails ?
"shown which may lead to unsafe logging of potentially sensitive data" :
"masked to prevent unsafe logging of potentially sensitive data";
logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
"': request parameters and headers will be " + value);
}
if (logger.isInfoEnabled()) {
logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
}
}
여기에서 간단한 몇 가지 방법의 호출만 볼 수 있고 스프링의 웹 상하문 초기화와 다른 초기화를 각각 완성했다. 그 중에서 뒤의 초기화는 논리를 스스로 정의할 수 있고 기본값은 비어 있다.여기서는 주로 상하 문장의 초기화를 본다.
protected WebApplicationContext initWebApplicationContext() {
// WebApplicationContext , ServletContext WebApplicationContext, WebApplicationContext.class.getName() + ".ROOT"
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
// webApplicationContext null, , spring , , true
if (this.webApplicationContext != null) {
//
wac = this.webApplicationContext;
// ConfigurableWebApplicationContext , WebApplicationContext
if (wac instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
// , ,
if (!cwac.isActive()) {
//
if (cwac.getParent() == null) {
cwac.setParent(rootContext);
}
// web
configureAndRefreshWebApplicationContext(cwac);
}
}
}
// wac null, web null, servlet web , FrameworkServlet.class.getName() + ".CONTEXT."+ servlet
if (wac == null) {
wac = findWebApplicationContext();
}
// servlet ,
if (wac == null) {
wac = createWebApplicationContext(rootContext);
}
// onRefresh
if (!this.refreshEventReceived) {
synchronized (this.onRefreshMonitor) {
// , servlet 。
onRefresh(wac);
}
}
// ServletContext , true
if (this.publishContext) {
// FrameworkServlet.class.getName() + ".CONTEXT."+ servlet
String attrName = getServletContextAttributeName();
// servlet
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
여기서 논리의 주요 두 가지 측면에서 사용할 수 있는 웹 응용 프로그램의 상하문을 찾은 다음에 시간의 발표와 다른 리셋 작업을 진행한다.여기서 몇 가지를 설명해야 할 것은:
initServletBean
은nullwebApplicationContext
의 판단은true이다.두 번째 점에 대해
isActive
가 언제 설치되었는지 설명하자면 webApplicationContext
인터페이스가 실현되었기 때문에 FrameworkServlet
실례화 후 초기화하기 전에 실현된 ApplicationContextAware
방법을 호출할 것이다.
public void setApplicationContext(ApplicationContext applicationContext) {
if (this.webApplicationContext == null && applicationContext instanceof WebApplicationContext) {
this.webApplicationContext = (WebApplicationContext) applicationContext;
this.webApplicationContextInjected = true;
}
}
여기
FrameworkServlet
에 대응하는 앞의 스프링의 생명주기에 대한 글은 스프링 소스 - 스프링의 빈 생명주기 흐름도와 코드 해석을 볼 수 있습니다.4.spring 관련 웹 관련 클래스 초기화
setApplicationContext
4.1 서브렛의 일반적인 정책 초기화우리는
ApplicationContextAware
중의 DispatcherServlet
방법에서 이러한 절차가 있음을 알아차렸다. 웹 응용 프로그램의 상하문을 찾은 후에 FrameworkServlet
방법이 이미 호출되었는지 검사하는 절차가 있을 것이다. 호출되지 않으면 대응하는 initWebApplicationContext
방법을 호출하고 호출되면 처리하지 않으면 어디에서 호출되었는가.지금 분석하려면 이것과 관련이 있다. onRefresh
방법은 onRefresh
에서 공 논리이고 그 주요 논리는 onRefresh
이류에서 진행된다.이제 안으로 들어갑니다. @Override
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
/**
* Initialize the strategy objects that this servlet uses.
* May be overridden in subclasses in order to initialize further strategy objects.
*/
protected void initStrategies(ApplicationContext context) {
// MultipartResolver, bean,
initMultipartResolver(context);
// LocaleResolver, bean,
initLocaleResolver(context);
// ThemeResolver, bean,
initThemeResolver(context);
// handlerMapping, HandlerMapping bean
initHandlerMappings(context);
// HandlerAdapter, HandlerAdapter bean
initHandlerAdapters(context);
// HandlerExceptionResolver, HandlerExceptionResolver bean,
initHandlerExceptionResolvers(context);
// (url) (url) RequestToViewNameTranslator, bean,
initRequestToViewNameTranslator(context);
// ViewResolver , ViewResolver bean,
initViewResolvers(context);
// FlashMapManager, FlashMap( url , direct )
initFlashMapManager(context);
}
익숙한 것들이 많이 나오는 것 같지 않아요? 맞아요. 이게 바로springmvc 전체가 쓸 수 있는 물건이에요. 여기에 싣고 저장하고 뒤에서 처리할 때 써요.여기까지spring의 웹 응용 프로그램이 사용할 수 있는 것은 여기에서 이미 초기화되었다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.