前文我们有了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的设计和初始化过程非常重要)

DispatcherServlet是如何初始化的?

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

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

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

init

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

  1. /**
  2. * Map config parameters onto bean properties of this servlet, and
  3. * invoke subclass initialization.
  4. * @throws ServletException if bean properties are invalid (or required
  5. * properties are missing), or if subclass initialization fails.
  6. */
  7. @Override
  8. public final void init() throws ServletException {
  9. // 读取web.xml中的servlet配置
  10. PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
  11. if (!pvs.isEmpty()) {
  12. try {
  13. // 转换成BeanWrapper,为了方便使用Spring的属性注入功能
  14. BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
  15. // 注入Resource类型需要依赖于ResourceEditor解析,所以注册Resource类关联到ResourceEditor解析器
  16. ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
  17. bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
  18. // 更多的初始化可以让子类去拓展
  19. initBeanWrapper(bw);
  20. // 让spring注入namespace,contextConfigLocation等属性
  21. bw.setPropertyValues(pvs, true);
  22. }
  23. catch (BeansException ex) {
  24. if (logger.isErrorEnabled()) {
  25. logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
  26. }
  27. throw ex;
  28. }
  29. }
  30. // 让子类去拓展
  31. initServletBean();
  32. }

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

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

  1. /**
  2. * Overridden method of {@link HttpServletBean}, invoked after any bean properties
  3. * have been set. Creates this servlet's WebApplicationContext.
  4. */
  5. @Override
  6. protected final void initServletBean() throws ServletException {
  7. getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'");
  8. if (logger.isInfoEnabled()) {
  9. logger.info("Initializing Servlet '" + getServletName() + "'");
  10. }
  11. long startTime = System.currentTimeMillis();
  12. try {
  13. // 最重要的是这个方法
  14. this.webApplicationContext = initWebApplicationContext();
  15. // 可以让子类进一步拓展
  16. initFrameworkServlet();
  17. }
  18. catch (ServletException | RuntimeException ex) {
  19. logger.error("Context initialization failed", ex);
  20. throw ex;
  21. }
  22. if (logger.isDebugEnabled()) {
  23. String value = this.enableLoggingRequestDetails ?
  24. "shown which may lead to unsafe logging of potentially sensitive data" :
  25. "masked to prevent unsafe logging of potentially sensitive data";
  26. logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails +
  27. "': request parameters and headers will be " + value);
  28. }
  29. if (logger.isInfoEnabled()) {
  30. logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
  31. }
  32. }

initWebApplicationContext

initWebApplicationContext用来初始化和刷新WebApplicationContext。

initWebApplicationContext() 方法如下

  1. /**
  2. * Initialize and publish the WebApplicationContext for this servlet.
  3. * <p>Delegates to {@link #createWebApplicationContext} for actual creation
  4. * of the context. Can be overridden in subclasses.
  5. * @return the WebApplicationContext instance
  6. * @see #FrameworkServlet(WebApplicationContext)
  7. * @see #setContextClass
  8. * @see #setContextConfigLocation
  9. */
  10. protected WebApplicationContext initWebApplicationContext() {
  11. WebApplicationContext rootContext =
  12. WebApplicationContextUtils.getWebApplicationContext(getServletContext());
  13. WebApplicationContext wac = null;
  14. // 如果在构造函数已经被初始化
  15. if (this.webApplicationContext != null) {
  16. // A context instance was injected at construction time -> use it
  17. wac = this.webApplicationContext;
  18. if (wac instanceof ConfigurableWebApplicationContext) {
  19. ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
  20. if (!cwac.isActive()) {
  21. // The context has not yet been refreshed -> provide services such as
  22. // setting the parent context, setting the application context id, etc
  23. if (cwac.getParent() == null) {
  24. // The context instance was injected without an explicit parent -> set
  25. // the root application context (if any; may be null) as the parent
  26. cwac.setParent(rootContext);
  27. }
  28. configureAndRefreshWebApplicationContext(cwac);
  29. }
  30. }
  31. }
  32. // 没有在构造函数中初始化,则尝试通过contextAttribute初始化
  33. if (wac == null) {
  34. // No context instance was injected at construction time -> see if one
  35. // has been registered in the servlet context. If one exists, it is assumed
  36. // that the parent context (if any) has already been set and that the
  37. // user has performed any initialization such as setting the context id
  38. wac = findWebApplicationContext();
  39. }
  40. // 还没有的话,只能重新创建了
  41. if (wac == null) {
  42. // No context instance is defined for this servlet -> create a local one
  43. wac = createWebApplicationContext(rootContext);
  44. }
  45. if (!this.refreshEventReceived) {
  46. // Either the context is not a ConfigurableApplicationContext with refresh
  47. // support or the context injected at construction time had already been
  48. // refreshed -> trigger initial onRefresh manually here.
  49. synchronized (this.onRefreshMonitor) {
  50. onRefresh(wac);
  51. }
  52. }
  53. if (this.publishContext) {
  54. // Publish the context as a servlet context attribute.
  55. String attrName = getServletContextAttributeName();
  56. getServletContext().setAttribute(attrName, wac);
  57. }
  58. return wac;
  59. }

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

创建的createWebApplicationContext方法如下

  1. /**
  2. * Instantiate the WebApplicationContext for this servlet, either a default
  3. * {@link org.springframework.web.context.support.XmlWebApplicationContext}
  4. * or a {@link #setContextClass custom context class}, if set.
  5. * <p>This implementation expects custom contexts to implement the
  6. * {@link org.springframework.web.context.ConfigurableWebApplicationContext}
  7. * interface. Can be overridden in subclasses.
  8. * <p>Do not forget to register this servlet instance as application listener on the
  9. * created context (for triggering its {@link #onRefresh callback}, and to call
  10. * {@link org.springframework.context.ConfigurableApplicationContext#refresh()}
  11. * before returning the context instance.
  12. * @param parent the parent ApplicationContext to use, or {@code null} if none
  13. * @return the WebApplicationContext for this servlet
  14. * @see org.springframework.web.context.support.XmlWebApplicationContext
  15. */
  16. protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {
  17. Class<?> contextClass = getContextClass();
  18. if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
  19. throw new ApplicationContextException(
  20. "Fatal initialization error in servlet with name '" + getServletName() +
  21. "': custom WebApplicationContext class [" + contextClass.getName() +
  22. "] is not of type ConfigurableWebApplicationContext");
  23. }
  24. // 通过反射方式初始化
  25. ConfigurableWebApplicationContext wac =
  26. (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
  27. wac.setEnvironment(getEnvironment());
  28. wac.setParent(parent);
  29. String configLocation = getContextConfigLocation(); // 就是前面Demo中的springmvc.xml
  30. if (configLocation != null) {
  31. wac.setConfigLocation(configLocation);
  32. }
  33. // 初始化Spring环境
  34. configureAndRefreshWebApplicationContext(wac);
  35. return wac;
  36. }

configureAndRefreshWebApplicationContext方法初始化设置Spring环境

  1. protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
  2. // 设置context ID
  3. if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
  4. // The application context id is still set to its original default value
  5. // -> assign a more useful id based on available information
  6. if (this.contextId != null) {
  7. wac.setId(this.contextId);
  8. }
  9. else {
  10. // Generate default id...
  11. wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
  12. ObjectUtils.getDisplayString(getServletContext().getContextPath()) + '/' + getServletName());
  13. }
  14. }
  15. // 设置servletContext, servletConfig, namespace, listener...
  16. wac.setServletContext(getServletContext());
  17. wac.setServletConfig(getServletConfig());
  18. wac.setNamespace(getNamespace());
  19. wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));
  20. // The wac environment's #initPropertySources will be called in any case when the context
  21. // is refreshed; do it eagerly here to ensure servlet property sources are in place for
  22. // use in any post-processing or initialization that occurs below prior to #refresh
  23. ConfigurableEnvironment env = wac.getEnvironment();
  24. if (env instanceof ConfigurableWebEnvironment) {
  25. ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());
  26. }
  27. // 让子类去拓展
  28. postProcessWebApplicationContext(wac);
  29. applyInitializers(wac);
  30. // Spring环境初始化完了,就可以初始化DispatcherServlet处理流程中需要的组件了。
  31. wac.refresh();
  32. }

refresh

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

  1. /**
  2. * This implementation calls {@link #initStrategies}.
  3. */
  4. @Override
  5. protected void onRefresh(ApplicationContext context) {
  6. initStrategies(context);
  7. }

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

  1. /**
  2. * Initialize the strategy objects that this servlet uses.
  3. * <p>May be overridden in subclasses in order to initialize further strategy objects.
  4. */
  5. protected void initStrategies(ApplicationContext context) {
  6. initMultipartResolver(context);
  7. initLocaleResolver(context);
  8. initThemeResolver(context);
  9. // 主要看如下三个方法
  10. initHandlerMappings(context);
  11. initHandlerAdapters(context);
  12. initHandlerExceptionResolvers(context);
  13. initRequestToViewNameTranslator(context);
  14. initViewResolvers(context);
  15. initFlashMapManager(context);
  16. }

initHanlderxxx

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

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

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

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

  1. /**
  2. * Initialize the HandlerAdapters used by this class.
  3. * <p>If no HandlerAdapter beans are defined in the BeanFactory for this namespace,
  4. * we default to SimpleControllerHandlerAdapter.
  5. */
  6. private void initHandlerAdapters(ApplicationContext context) {
  7. this.handlerAdapters = null;
  8. if (this.detectAllHandlerAdapters) {
  9. // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
  10. Map<String, HandlerAdapter> matchingBeans =
  11. BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
  12. if (!matchingBeans.isEmpty()) {
  13. this.handlerAdapters = new ArrayList<>(matchingBeans.values());
  14. // We keep HandlerAdapters in sorted order.
  15. AnnotationAwareOrderComparator.sort(this.handlerAdapters);
  16. }
  17. }
  18. else {
  19. try {
  20. HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
  21. this.handlerAdapters = Collections.singletonList(ha);
  22. }
  23. catch (NoSuchBeanDefinitionException ex) {
  24. // Ignore, we'll add a default HandlerAdapter later.
  25. }
  26. }
  27. // Ensure we have at least some HandlerAdapters, by registering
  28. // default HandlerAdapters if no other adapters are found.
  29. if (this.handlerAdapters == null) {
  30. this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
  31. if (logger.isTraceEnabled()) {
  32. logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
  33. "': using default strategies from DispatcherServlet.properties");
  34. }
  35. }
  36. }
  37. /**
  38. * Initialize the HandlerExceptionResolver used by this class.
  39. * <p>If no bean is defined with the given name in the BeanFactory for this namespace,
  40. * we default to no exception resolver.
  41. */
  42. private void initHandlerExceptionResolvers(ApplicationContext context) {
  43. this.handlerExceptionResolvers = null;
  44. if (this.detectAllHandlerExceptionResolvers) {
  45. // Find all HandlerExceptionResolvers in the ApplicationContext, including ancestor contexts.
  46. Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
  47. .beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false);
  48. if (!matchingBeans.isEmpty()) {
  49. this.handlerExceptionResolvers = new ArrayList<>(matchingBeans.values());
  50. // We keep HandlerExceptionResolvers in sorted order.
  51. AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
  52. }
  53. }
  54. else {
  55. try {
  56. HandlerExceptionResolver her =
  57. context.getBean(HANDLER_EXCEPTION_RESOLVER_BEAN_NAME, HandlerExceptionResolver.class);
  58. this.handlerExceptionResolvers = Collections.singletonList(her);
  59. }
  60. catch (NoSuchBeanDefinitionException ex) {
  61. // Ignore, no HandlerExceptionResolver is fine too.
  62. }
  63. }
  64. // Ensure we have at least some HandlerExceptionResolvers, by registering
  65. // default HandlerExceptionResolvers if no other resolvers are found.
  66. if (this.handlerExceptionResolvers == null) {
  67. this.handlerExceptionResolvers = getDefaultStrategies(context, HandlerExceptionResolver.class);
  68. if (logger.isTraceEnabled()) {
  69. logger.trace("No HandlerExceptionResolvers declared in servlet '" + getServletName() +
  70. "': using default strategies from DispatcherServlet.properties");
  71. }
  72. }
  73. }

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

  1. 21:30:33.163 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.web.servlet.DispatcherServlet - Initializing Servlet 'springmvc-demo'
  2. 21:30:38.242 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.context.support.XmlWebApplicationContext - Refreshing WebApplicationContext for namespace 'springmvc-demo-servlet'
  3. 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]
  4. 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]
  5. 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]
  6. 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]
  7. 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'
  8. 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'
  9. 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'
  10. 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'
  11. 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'
  12. 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]
  13. 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'
  14. 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'
  15. 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'
  16. 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'
  17. 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'
  18. 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'
  19. 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'
  20. 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. 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'
  22. 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'
  23. 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' {}
  24. 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'
  25. 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'
  26. 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'
  27. 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'
  28. 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'
  29. 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'
  30. 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'
  31. 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'
  32. 21:30:41.150 [RMI TCP Connection(2)-127.0.0.1] DEBUG _org.springframework.web.servlet.HandlerMapping.Mappings -
  33. t.p.s.s.c.UserController:
  34. { [/user]}: list(HttpServletRequest,HttpServletResponse)
  35. 21:30:41.202 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - 1 mappings in 'org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping'
  36. 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'
  37. 21:30:41.626 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none
  38. 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'
  39. 21:30:41.786 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - ControllerAdvice beans: none
  40. 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'
  41. 21:30:41.919 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - ControllerAdvice beans: none
  42. 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'
  43. 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'
  44. 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'
  45. 21:30:44.214 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected AcceptHeaderLocaleResolver
  46. 21:30:44.214 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.web.servlet.DispatcherServlet - Detected FixedThemeResolver
  47. 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
  48. 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
  49. 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]
  50. 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]。
  51. 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]
  52. 21:44:08.185 [RMI TCP Connection(2)-127.0.0.1] DEBUG org.springframework.jndi.JndiPropertySource - JNDI lookup for name [spring.liveBeansView.mbeanDomain] threw NamingException with message: 名称[spring.liveBeansView.mbeanDomain]未在此上下文中绑定。找不到[spring.liveBeansView.mbeanDomain]。. Returning null.
  53. 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
  54. 21:44:08.195 [RMI TCP Connection(2)-127.0.0.1] INFO org.springframework.web.servlet.DispatcherServlet - Completed initialization in 815032 ms

更多文章

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

  • Spring基础 - Spring和Spring框架组成

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

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

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

  • Spring基础 - SpringMVC请求流程和案例

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

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

  • Spring进阶 - Spring IOC实现原理详解之IOC体系结构设计

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

Spring框架系列(13) - SpringMVC实现原理之DispatcherServlet的初始化过程的更多相关文章

  1. Spring框架系列(14) - SpringMVC实现原理之DispatcherServlet处理请求的过程

    前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet ...

  2. Spring框架系列(5) - 深入浅出SpringMVC请求流程和案例

    前文我们介绍了Spring框架和Spring框架中最为重要的两个技术点(IOC和AOP),那我们如何更好的构建上层的应用呢(比如web 应用),这便是SpringMVC:Spring MVC是Spri ...

  3. Spring框架系列(6) - Spring IOC实现原理详解之IOC体系结构设计

    在对IoC有了初步的认知后,我们开始对IOC的实现原理进行深入理解.本文将帮助你站在设计者的角度去看IOC最顶层的结构设计.@pdai Spring框架系列(6) - Spring IOC实现原理详解 ...

  4. Spring框架系列(7) - Spring IOC实现原理详解之IOC初始化流程

    上文,我们看了IOC设计要点和设计结构:紧接着这篇,我们可以看下源码的实现了:Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的. ...

  5. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  6. Spring框架系列(9) - Spring AOP实现原理详解之AOP切面的实现

    前文,我们分析了Spring IOC的初始化过程和Bean的生命周期等,而Spring AOP也是基于IOC的Bean加载来实现的.本文主要介绍Spring AOP原理解析的切面实现过程(将切面类的所 ...

  7. Spring框架系列(10) - Spring AOP实现原理详解之AOP代理的创建

    上文我们介绍了Spring AOP原理解析的切面实现过程(将切面类的所有切面方法根据使用的注解生成对应Advice,并将Advice连同切入点匹配器和切面类等信息一并封装到Advisor).本文在此基 ...

  8. Spring框架系列(11) - Spring AOP实现原理详解之Cglib代理实现

    我们在前文中已经介绍了SpringAOP的切面实现和创建动态代理的过程,那么动态代理是如何工作的呢?本文主要介绍Cglib动态代理的案例和SpringAOP实现的原理.@pdai Spring框架系列 ...

  9. Spring框架系列(12) - Spring AOP实现原理详解之JDK代理实现

    上文我们学习了SpringAOP Cglib动态代理的实现,本文主要是SpringAOP JDK动态代理的案例和实现部分.@pdai Spring框架系列(12) - Spring AOP实现原理详解 ...

随机推荐

  1. 在 WinForms 项目中使用全局快捷键

    借助于全局快捷键,用户可以在任何地方操控程序,触发对应的功能.但 WinForms 框架并没有提供全局快捷键的功能.想要实现全局快捷键需要跟 Windows API 打交道.本文就交你如何使用 Win ...

  2. Exception in thread "main" java.awt.AWTError: Assistive Technology not found: org.GNOME.Accessibilit

    系统环境 Ubuntu 20.04 focal 问题分析 该异常出现的原因,从谷歌上可以得到答案 one of the more common causes of this exception is ...

  3. python学习-Day37

    目录 今日内容详细 GIL全局解释器锁 GIL与普通互斥锁区别 GIL对程序的影响 验证多线程作用 两个大前提 关于CPU的个数 关于任务的类型 死锁现象 避免死锁的解决: 添加超时释放锁 信号量 自 ...

  4. netty系列之:netty中的自动解码器ReplayingDecoder

    目录 简介 ByteToMessageDecoder可能遇到的问题 ReplayingDecoder的实现原理 总结 简介 netty提供了一个从ByteBuf到用户自定义的message的解码器叫做 ...

  5. Mybatis执行多条SQL

    1:在数据库连接配置文件处,增加如下参数即可:allowMultiQueries=true spring: datasource: url: jdbc:mysql://IP:PORT/数据库名?其他参 ...

  6. LintCode-165 · 合并两个排序链表-题解

    描述:将两个排序(升序)链表合并为一个新的升序排序链表样例 1:输入: list1 = null, list2 = 0->3->3->null输出: 0->3->3-&g ...

  7. kubeadm高可用master节点(三主两从)

    1.安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: 五台机器,操作系统 CentOS7.5+(mini) 硬件配置:2GBRAM,2vCPU+,硬盘30GB+ 集群中所有 ...

  8. Centos 7防火墙策略配置指南

    Centos 7防火墙策略配置指南 -- 清听凌雪慕忆 @ 目录 1. 开启防火墙 1.1 user切换到root用户 1.2 查看防火墙服务状态 1.3 查看firewall的状态 1.4 启动/关 ...

  9. hashib加密模块、logging模块

    hashib加密模块 # 加密模块 1.什么是加密 将明文的数据通过一些手段变成能密文数据 密文数据的表现形式一般都是一串没有规则的字符串 2.加密算法 加密算法有很多>>>(讲文明 ...

  10. Web 后端的一生之敌:分页器

    分页器是 Web 开发中常见的功能,看似简单的却经常隐藏着各种奇怪的坑,堪称 WEB 后端开发的一生之敌. 常见问题 边翻页边写入导致内容重复 某位用户正在浏览我的博客,他看到第一页最后一篇文章是 & ...