zoukankan      html  css  js  c++  java
  • 从springmvc启动日志学习

    javaee标准中,tomcat等web容器启动时走web.xml 先将各种contex-param 放到servletcontxt中变成parameter,然后开始启动容器,容器对外提供了listener可在容器onstartup时做一些操作。

     

    log:

     

    二月 25, 2017 2:56:16 下午 org.apache.catalina.core.ApplicationContext log

    信息: No Spring WebApplicationInitializer types detected on classpath

     

    解释:---没找到自定义的spring WebApplicationInitializer

    这句日志来自于: org.springframework.web.SpringServletContainerInitializer 在spring-web-x.x.x.Release.jar 包中。

    该类实现了servletContainerInitializer 接口的onStartup方法。此接口只有一个方法。这是spring3.1之后的新特性,无web.xml 而是基于代码注解的配置启动servlet。引入了servlet3.0.

     

     * @param c the Set of application classes that extend, implement, or

     * have been annotated with the class types specified by the 

     * {@link javax.servlet.annotation.HandlesTypes HandlesTypes} annotation,

     * or <tt>null</tt> if there are no matches, or this

     * <tt>ServletContainerInitializer</tt> has not been annotated with

     * <tt>HandlesTypes</tt>

    c这个param比较有意思,需要实现类增加@HandlesTypes(xx.class)注解。如spring的实现类声明了注解

    @HandlesTypes(WebApplicationInitializer.class) 所以spring基于java代码的配置是需要实现WebApplicationInitializer接口的。

     

     

     

    @since Servlet 3.0

    public interface ServletContainerInitializer {

        public void onStartup(Set<Class<?>> c, ServletContext ctx)

            throws ServletException; 

    }

     

    查看此接口的注释

    <p>Implementations of this interface must be declared by a JAR file
     * resource located inside the <tt>META-INF/services</tt> directory and
     * named for the fully qualified class name of this interface, and will be 
     * discovered using the runtime's service provider lookup mechanism
     * or a container specific mechanism that is semantically equivalent to
     * it.

    大概意思是讲 必须在该接口所在项目的META-INF/services/文件夹下 生成一个文件名字为javax.serlvet.ServletContainerInitializer的文件,内容要与ServletContainerInitializer接口的实现类的全路径一样才能被发现。

    仔细看spring-web包下 有类似的结构。声明为了javax.servlet.ServletContainerInitializer的文件,内容为 org.springframework.web.SpringServletContainerInitializer

    日志来自于实现类:SpringServletContainerInitializer上一段源码:

     
    @Override
    	public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
    			throws ServletException {
    
    		List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>();
    
    		if (webAppInitializerClasses != null) {
    			for (Class<?> waiClass : webAppInitializerClasses) {
    				// Be defensive: Some servlet containers provide us with invalid classes,
    				// no matter what @HandlesTypes says...
    				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
    						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
    					try {
    						initializers.add((WebApplicationInitializer) waiClass.newInstance());
    					}
    					catch (Throwable ex) {
    						throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
    					}
    				}
    			}
    		}
    
    		if (initializers.isEmpty()) {
    			servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
    			return;
    		}
    
    		AnnotationAwareOrderComparator.sort(initializers);
    		servletContext.log("Spring WebApplicationInitializers detected on classpath: " + initializers);
    
    		for (WebApplicationInitializer initializer : initializers) {
    			initializer.onStartup(servletContext);
    		}
    	}
    

      

    因为没有使用基于servlet3.0规范的类,所以有这一条日志。
     

     

     

    log:

     

    Initializing Spring root WebApplicationContext

     

    解释:日志是由类

    WebApplicationContextorg.springframework.web.context.ContextLoader.initWebApplicationContext(ServletContext servletContext)打印的,contextLoader作为ContextLoaderListener的private 变量。标识着启动wac。核心代码在wac.refresh()中。

    值得注意的是注册核心类之前,会先处理beanFactory的PostProcesors类。

    这些类一般都实现了 

    BeanFactoryPostProcessor 这个接口。通常讲抽象类PropertyResourceConfigurer比较重要。

    org.springframework.beans.factory.config.PropertyResourceConfigurer

    源码注释:
    /* Allows for custom modification of an application context's bean definitions, * adapting the bean property values of the context's underlying bean factory. * * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in * their bean definitions and apply them before any other beans get created. * * <p>Useful for custom config files targeted at system administrators that * override bean properties configured in the application context.

      */

     

     

    LOG:

    2017-02-25 19:29:08:719  INFO  [mvc.annotation.DefaultAnnotationHandlerMapping] Mapped URL path

     

    解释:

    启动wac时,会由读取@RequestMapping 注解拼接url ,并缓存 {url,method}的映射关系。

     

    LOG:

    二月 25, 2017 7:40:29 下午 org.apache.catalina.core.ApplicationContext log

    信息: Initializing Spring FrameworkServlet 'led'

    2017-02-25 19:40:29:584  INFO  [web.servlet.DispatcherServlet] FrameworkServlet 'led': initialization started

    2017-02-25 19:40:29:603  INFO  [context.support.XmlWebApplicationContext] Refreshing WebApplicationContext for namespace 'led-servlet': startup date [Sat Feb 25 19:40:29 CST 2017]; parent: Root WebApplicationContext

    2017-02-25 19:40:29:605  INFO  [factory.xml.XmlBeanDefinitionReader] Loading XML bean definitions from ServletContext resource [/WEB-INF/led-servlet.xml]

     

     

     

    解释:开始启动servlet,配置为DispatcherServlet 并执行父类 FrameworkServlet 的父类 HttpServletBean的init方法,并钩子调用FrameworkServlet的initServletBean()创建servlet容器 放到servletContext

    setAttribute(Framework.class.getName()+".CONTEXT"+ServletName,WAC);并且将WAC的parent设置为ContextLoaderListener创建的WAC。

     

     

    至此SpringMVC启动完毕。

    更加详细的内容下一篇随笔。

     

  • 相关阅读:
    8月面试题目收录
    html5读取本地文件,图片预览
    Identity Server4资料
    vue与Element实际应用参考
    webpack与vue环境搭建(转载)
    .NET使用Bogus生成大量随机数据(转载)
    Docker笔记:常用服务安装——Nginx、MySql、Redis(转载)
    RabbitMQ操作代码封装
    RSA加密与解密
    .NET CORE编写控制台程序应有的优雅姿势(转载)
  • 原文地址:https://www.cnblogs.com/luoluoshidafu/p/6442579.html
Copyright © 2011-2022 走看看