Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程

Posted realpdai

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程相关的知识,希望对你有一定的参考价值。


前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet处理请求的过程的源码解析。本文是第一篇:DispatcherServlet的初始化过程的源码解析。@pdai


DispatcherServlet和ApplicationContext有何关系?


DispatcherServlet 作为一个 Servlet,需要根据 Servlet 规范使用 Java 配置或 web.xml 声明和映射。反过来,DispatcherServlet 使用 Spring 配置来发现请求映射、视图解析、异常处理等等所需的委托组件。那它和ApplicationContext有和关系呢?如下内容可以参考​​官网-SpringMVC文档​


DispatcherServlet 需要 WebApplicationContext(继承自 ApplicationContext) 来配置。WebApplicationContext 可以链接到ServletContext 和 Servlet。因为绑定了 ServletContext,这样应用程序就可以在需要的时候使用 RequestContextUtils 的静态方法访问 WebApplicationContext。

大多数应用程序只有一个WebApplicationContext,除此之外也可以一个Root WebApplicationContext 被多个 Servlet实例,然后各自拥有自己的Servlet WebApplicationContext 配置。

Root WebApplicationContext 包含需要共享给多个 Servlet 实例的数据源和业务服务基础 Bean。这些 Bean 可以在 Servlet 特定的范围被继承或覆盖。

(PS:官网上的这张图可以可以帮助你构建DispatcherServlet和ApplicationContext在设计上的认知,这一点对于理解DispatcherServlet的设计和初始化过程非常重要)

Spring框架系列(13)

DispatcherServlet是如何初始化的?


DispatcherServlet首先是Sevlet,Servlet有自己的生命周期的方法(init,destory等),那么我们在看DispatcherServlet初始化时首先需要看源码中DispatcherServlet的类结构设计。


首先我们看DispatcherServlet的类结构关系,在这个类依赖结构中找到init的方法

Spring框架系列(13)

很容易找到init()的方法位于HttpServletBean中,然后跑​​Spring基础 - SpringMVC请求流程和案例​​中的代码,在init方法中打断点。

Spring框架系列(13)

init

init()方法如下, 主要读取web.xml中servlet参数配置,并将交给子类方法initServletBean()继续初始化

/**
* Map config parameters onto bean properties of this servlet, and
* invoke subclass initialization.
* @throws ServletException if bean properties are invalid (or required
* properties are missing), or if subclass initialization fails.
*/
@Override
() ServletException

// 读取web.xml中的servlet配置
PropertyValues pvs = ServletConfigPropertyValues(getServletConfig(), .requiredProperties);
(!pvs.isEmpty())

// 转换成BeanWrapper,为了方便使用Spring的属性注入功能
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess();
// 注入Resource类型需要依赖于ResourceEditor解析,所以注册Resource类关联到ResourceEditor解析器
ResourceLoader resourceLoader = ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource., (, ()));
// 更多的初始化可以让子类去拓展
initBeanWrapper(bw);
// 让spring注入namespace,contextConfigLocation等属性
bw.setPropertyValues(pvs, );

(BeansException ex)
(logger.isErrorEnabled())
logger.error("Failed to set bean properties on servlet " + getServletName() + "", ex);

ex;



// 让子类去拓展
initServletBean();

读取配置可以从下图看出,正是初始化了我们web.xml中配置

Spring框架系列(13)

再看下initServletBean()方法,位于FrameworkServlet类中

/**
* Overridden method of @link HttpServletBean, invoked after any bean properties
* have been set. Creates this servlets WebApplicationContext.
*/
@Override
() ServletException
getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " " + getServletName() + "");
(logger.isInfoEnabled())
logger.info("Initializing Servlet " + getServletName() + "");

startTime = System.currentTimeMillis();


// 最重要的是这个方法
.webApplicationContext = initWebApplicationContext();

// 可以让子类进一步拓展
initFrameworkServlet();

(ServletException | RuntimeException ex)
logger.error("Context initialization failed", ex);
ex;


(logger.isDebugEnabled())
String value = .enableLoggingRequestDetails ?
"shown which may lead to unsafe logging of potentially sensitive data" :
"masked to prevent unsafe logging of potentially sensitive data";
logger.debug("enableLoggingRequestDetails=" + .enableLoggingRequestDetails +
": request parameters and headers will be " + value);


(logger.isInfoEnabled())
logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");

initWebApplicationContext

initWebApplicationContext用来初始化和刷新WebApplicationContext。

initWebApplicationContext() 方法如下

/**
* Initialize and publish the WebApplicationContext for this servlet.
* <p>Delegates to @link #createWebApplicationContext for actual creation
* of the context. Can be overridden in subclasses.
* @return the WebApplicationContext instance
* @see #FrameworkServlet(WebApplicationContext)
* @see #setContextClass
* @see #setContextConfigLocation
*/
WebApplicationContext ()
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = ;

// 如果在构造函数已经被初始化
(.webApplicationContext != )
// A context instance was injected at construction time -> use it
wac = .webApplicationContext;
(wac ConfigurableWebApplicationContext)
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
(!cwac.isActive())
// The context has not yet been refreshed -> provide services such as
// setting the parent context, setting the application context id, etc
(cwac.getParent() == )
// The context instance was injected without an explicit parent -> set
// the root application context (if any; may be null) as the parent
cwac.setParent(rootContext);

configureAndRefreshWebApplicationContext(cwac);



// 没有在构造函数中初始化,则尝试通过contextAttribute初始化
(wac == )
// No context instance was injected at construction time -> see if one
// has been registered in the servlet context. If one exists, it is assumed
// that the parent context (if any) has already been set and that the
// user has performed any initialization such as setting the context id
wac = findWebApplicationContext();


// 还没有的话,只能重新创建了
(wac == )
// No context instance is defined for this servlet -> create a local one
wac = createWebApplicationContext(rootContext);


(!.refreshEventReceived)
// Either the context is not a ConfigurableApplicationContext with refresh
// support or the context injected at construction time had already been
// refreshed -> trigger initial onRefresh manually here.
(.onRefreshMonitor)
onRefresh(wac);



(.publishContext)
// Publish the context as a servlet context attribute.
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);


wac;

webApplicationContext只会初始化一次,依次尝试构造函数初始化,没有则通过contextAttribute初始化,仍没有则创建新的

创建的createWebApplicationContext方法如下

/**
* Instantiate the WebApplicationContext for this servlet, either a default
* @link org.springframework.web.context.support.XmlWebApplicationContext
* or a @link #setContextClass custom context class, if set.
* <p>This implementation expects custom contexts to implement the
* @link org.springframework.web.context.ConfigurableWebApplicationContext
* interface. Can be overridden in subclasses.
* <p>Do not forget to register this servlet instance as application listener on the
* created context (for triggering its @link #onRefresh callback, and to call
* @link org.springframework.context.ConfigurableApplicationContext#refresh()
* before returning the context instance.
* @param parent the parent ApplicationContext to use, or @code null if none
* @return the WebApplicationContext for this servlet
* @see org.springframework.web.context.support.XmlWebApplicationContext
*/
WebApplicationContext (@Nullable ApplicationContext parent)
Class<?> contextClass = getContextClass();
(!ConfigurableWebApplicationContext..())
ApplicationContextException(
"Fatal initialization error in servlet with name " + getServletName() +
": custom WebApplicationContext class [" + contextClass.getName() +
"] is not of type ConfigurableWebApplicationContext");


// 通过反射方式初始化
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

wac.setEnvironment(getEnvironment());
wac.setParent(parent);
String configLocation = getContextConfigLocation(); // 就是前面Demo中的springmvc.xml
(configLocation != )
wac.setConfigLocation(configLocation);


// 初始化Spring环境
configureAndRefreshWebApplicationContext(wac);

wac;

configureAndRefreshWebApplicationContext方法初始化设置Spring环境

(ConfigurableWebApplicationContext wac) 
// 设置context ID
(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
(.contextId != )
wac.setId(.contextId);


// Generate default id...
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(getServletContext().getContextPath()) + / + getServletName());



// 设置servletContext, servletConfig, namespace, listener...
wac.setServletContext(getServletContext());
wac.setServletConfig(getServletConfig());
wac.setNamespace(getNamespace());
wac.addApplicationListener( SourceFilteringListener(wac, ContextRefreshListener()));

// The wac environments #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();
(env ConfigurableWebEnvironment)
((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());


// 让子类去拓展
postProcessWebApplicationContext(wac);
applyInitializers(wac);

// Spring环境初始化完了,就可以初始化DispatcherServlet处理流程中需要的组件了。
wac.refresh();

refresh

有了webApplicationContext后,就开始刷新了(onRefresh()方法),这个方法是FrameworkServlet提供的模板方法,由子类DispatcherServlet来实现的。

/**
* This implementation calls @link #initStrategies.
*/
@Override
(ApplicationContext context)
initStrategies(context);

刷新主要是调用initStrategies(context)方法对DispatcherServlet中的组件进行初始化,这些组件就是在SpringMVC请求流程中包的主要组件。

/**
* Initialize the strategy objects that this servlet uses.
* <p>May be overridden in subclasses in order to initialize further strategy objects.
*/
(ApplicationContext context)
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);

// 主要看如下三个方法
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);

initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);

initHanlderxxx

我们主要看initHandlerXXX相关的方法,它们之间的关系可以看SpringMVC的请求流程:

Spring框架系列(13)

  1. HandlerMapping是映射处理器
  2. HandlerAdpter是处理适配器,它用来找到你的Controller中的处理方法
  3. HandlerExceptionResolver是当遇到处理异常时的异常解析器

initHandlerMapping方法如下,无非就是获取按照优先级排序后的HanlderMappings, 将来匹配时按照优先级最高的HanderMapping进行处理。

Spring框架系列(13)

initHandlerAdapters方法和initHandlerExceptionResolvers方法也是类似的,如果没有找到,那就构建默认的。

/**
* Initialize the HandlerAdapters used by this class.
* <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
* we default to SimpleControllerHandlerAdapter.
*/
(ApplicationContext context)
.handlerAdapters = ;

(.detectAllHandlerAdapters)
// Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter., , );
(!matchingBeans.isEmpty())
.handlerAdapters = ArrayList<>(matchingBeans.values());
// We keep HandlerAdapters in sorted order.
AnnotationAwareOrderComparator.sort(.handlerAdapters);




HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.);
.handlerAdapters = Collections.singletonList(ha);

(NoSuchBeanDefinitionException ex)
// Ignore, well add a default HandlerAdapter later.



// Ensure we have at least some HandlerAdapters, by registering
// default HandlerAdapters if no other adapters are found.
(.handlerAdapters == )
.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.);
(logger.isTraceEnabled())
logger.trace("No HandlerAdapters declared for servlet " + getServletName() +
": using default strategies from DispatcherServlet.properties");




/**
* Initialize the HandlerExceptionResolver used by this class.
* <p>If no bean is defined with the given name in the BeanFactory for this namespace,
* we default to no exception resolver.
*/
(ApplicationContext context)
.handlerExceptionResolvers = ;

(.detectAllHandlerExceptionResolvers)
// Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver., , );
(!matchingBeans.isEmpty())
.handlerExceptionResolvers = ArrayList<>(matchingBeans.values());
// We keep HandlerExceptionResolvers in sorted order.
AnnotationAwareOrderComparator.sort(.handlerExceptionResolvers);




HandlerExceptionResolver her =
context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.);
.handlerExceptionResolvers = Collections.singletonList(her);

(NoSuchBeanDefinitionException ex)
// Ignore, no HandlerExceptionResolver is fine too.



// Ensure we have at least some HandlerExceptionResolvers, by registering
// default HandlerExceptionResolvers if no other resolvers are found.
(.handlerExceptionResolvers == )
.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.);
(logger.isTraceEnabled())
logger.trace("No HandlerExceptionResolvers declared in servlet " + getServletName() +
": using default strategies from DispatcherServlet.properties");


最后我们看下初始化的日志:

21:30:33.163 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.web.servlet.DispatcherServlet - Initializing Servlet springmvc-demo
21:30:38.242 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext namespace springmvc-demo-servlet
21:30:39.256 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/pdai/pdai/www/tech-pdai-spring-demos/011-spring-framework-demo-springmvc/target/011-spring-framework-demo-springmvc-1.0-SNAPSHOT/WEB-INF/classes/tech/pdai/springframework/springmvc/controller/UserController.class]
21:30:39.261 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/pdai/pdai/www/tech-pdai-spring-demos/011-spring-framework-demo-springmvc/target/011-spring-framework-demo-springmvc-1.0-SNAPSHOT/WEB-INF/classes/tech/pdai/springframework/springmvc/dao/UserDaoImpl.class]
21:30:39.274 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [/Users/pdai/pdai/www/tech-pdai-spring-demos/011-spring-framework-demo-springmvc/target/011-spring-framework-demo-springmvc-1.0-SNAPSHOT/WEB-INF/classes/tech/pdai/springframework/springmvc/service/UserServiceImpl.class]
21:30:39.546 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 29 bean definitions from class path resource [springmvc.xml]
21:30:39.711 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.context.annotation.internalConfigurationAnnotationProcessor
21:30:39.973 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.context.event.internalEventListenerProcessor
21:30:39.984 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.context.event.internalEventListenerFactory
21:30:39.995 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.context.annotation.internalAutowiredAnnotationProcessor
21:30:40.003 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.context.annotation.internalCommonAnnotationProcessor
21:30:40.042 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.ui.context.support.UiApplicationContextUtils - Unable to locate ThemeSource with name themeSource: using default [org.springframework.ui.context.support.ResourceBundleThemeSource@791af912]
21:30:40.052 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean userController
21:30:40.136 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean userServiceImpl
21:30:40.140 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean userDaoImpl
21:30:40.147 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0
21:30:40.153 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0
21:30:40.350 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.handler.MappedInterceptor#0
21:30:40.356 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.format.support.FormattingConversionServiceFactoryBean#0
21:30:40.741 [RMI TCP Connection(2)-127.0.0.1] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings - org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0 /**=org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler@216c0f1f
21:30:40.742 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean mvcCorsConfigurations
21:30:40.742 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
21:30:40.792 [RMI TCP Connection(2)-127.0.0.1] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings - org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
21:30:40.792 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
21:30:40.793 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
21:30:40.794 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean localeResolver
21:30:40.796 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean themeResolver
21:30:40.798 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean viewNameTranslator
21:30:40.799 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean flashMapManager
21:30:40.805 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean mvcContentNegotiationManager
21:30:40.887 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
21:30:41.150 [RMI TCP Connection(2)-127.0.0.1] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings -
t.p.s.s.c.UserController:
[/user]: list(HttpServletRequest,HttpServletResponse)
21:30:41.202 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - 1 mappings org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
21:30:41.202 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
21:30:41.626 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none
21:30:41.738 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean mvcUriComponentsContributor
21:30:41.786 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none
21:30:41.806 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0
21:30:41.919 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - ControllerAdvice beans: none
21:30:41.920 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0
21:30:41.949 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0
21:30:41.967 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean jspViewResolver
21:30:44.214 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected AcceptHeaderLocaleResolver
21:30:44.214 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected FixedThemeResolver
21:31:02.141 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@d57bc91
21:31:03.483 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected org.springframework.web.servlet.support.SessionFlashMapManager@2b4e795e
21:44:08.180 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [java:comp/env/spring.liveBeansView.mbeanDomain]
21:44:08.185 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.jndi.JndiLocatorDelegate - Converted JNDI name [java:comp/env/spring.liveBeansView.mbeanDomain] not found - trying original name [spring.liveBeansView.mbeanDomain]. javax.naming.NameNotFoundException: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。
21:44:08.185 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.jndi.JndiTemplate - Looking up JNDI object with name [spring.liveBeansView.mbeanDomain]
21:44:08.185 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup name [spring.liveBeansView.mbeanDomain] threw NamingException with message: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。. Returning null.
21:44:08.195 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - enableLoggingRequestDetails=false: request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
21:44:08.195 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization 815032 ms

更多文章


首先, 从Spring框架的整体架构和组成对整体框架有个认知。


  • Spring是什么?它是怎么诞生的?有哪些主要的组件和核心功能呢? 本文通过这几个问题帮助你构筑Spring和Spring Framework的整体认知。


其次,通过案例引出Spring的核心(IoC和AOP),同时对IoC和AOP进行案例使用分析。


  • 上文中我们简单介绍了Spring和Spring Framework的组件,那么这些Spring Framework组件是如何配合工作的呢?本文主要承接上文,向你展示Spring Framework组件的典型应用场景和基于这个场景设计出的简单案例,并以此引出Spring的核心要点,比如IOC和AOP等;在此基础上还引入了不同的配置方式, 如XML,Java配置和注解方式的差异。


基于Spring框架和IOC,AOP的基础,为构建上层web应用,需要进一步学习SpringMVC。


  • 前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC;Spring MVC是Spring在Spring Container Core和AOP等技术基础上,遵循上述Web MVC的规范推出的web开发框架,目的是为了简化Java栈的web开发。 本文主要介绍SpringMVC的请求流程和基础案例的编写和运行。


Spring进阶 - IoC,AOP以及SpringMVC的源码分析


  • 在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解。本文将帮助你站在设计者的角度去看IOC最顶层的结构设计
  • 上文,我们看了IOC设计要点和设计结构;紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的
  • 上文,我们看了IOC设计要点和设计结构;以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的;容器中存放的是Bean的定义即BeanDefinition放到beanDefinitionMap中,本质上是一个ConcurrentHashMap<String, Object>;并且BeanDefinition接口中包含了这个类的Class信息以及是否是单例等。那么如何从BeanDefinition中实例化Bean对象呢,这是本文主要研究的内容?
  • 前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的。本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor,为后续交给代理增强实现做准备的过程)。
  • 上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor)。本文在此基础上继续介绍,代理(cglib代理和JDK代理)的实现过程。
  • 我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理。
  • 上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分。
  • 前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet处理请求的过程的源码解析。本文是第一篇:DispatcherServlet的初始化过程的源码解析。
  • 前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet处理请求的过程的源码解析。本文是第二篇:DispatcherServlet处理请求的过程的源码解析。

以上是关于Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程的主要内容,如果未能解决你的问题,请参考以下文章

spring,springmv,springboot解决跨域问题

Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程

ssm框架基本原理

ssm框架基本原理

Spring MVC程序

Spring