mvc项目结构启动流程Tomcat启动的时候会去war包中找SpringServletContainerInitializer这个类实例化后调用它的onStartUp方法。这个类有个HandlesTypes({WebApplicationInitializer.class}) 注解。tomcat看到这个注解会去war中找所有的WebApplicationInitializer实现类。并将实现类传给onStartUp方法。之后在这个方法中就会遍历所有的WebApplicationInitializer依次调用它们的onStartUp方法完成web环境初始化。项目中的WebInit类继承了AbstractAnnotationConfigDispatcherServletInitializer这个抽象类其实就是接口实现类。onStartUp的方法流程调用registerContextLoaderListener方法这个方法流程根据WebInit配置类中的getRootConfigClasses方法返回的根容器父容器配置类创建父容器。最终会得到一个AnnotationConfigWebApplicationContext。配置类会存到这个AC的componentClasses属性中。创建一个监听器ContextLoaderListener并放入servletContext由tomcat创建的上下文上面执行完了之后就有了父容器和监听器。现在再根据WebInit中的getServletConfigClasses返回的配置类以同样的流程创建子容器也是一个AnnotationConfigWebApplicationContext。调用createDispatcherServlet创建一个DispatcherServlettomcat的servletContext调用addServlet方法注册DispatcherServletsetLoadOnStartup设置Servlet优先级为1表示容器启动时就立刻初始化DS而不是等第一个请求来了之后懒加载addMapping设置拦截路径可以设置通配符。这个在WebInit的getServletMappings中配置的。为“/”时就是拦截所有请求setAsyncSupported是否支持异步registerServletFilter设置过滤器onStartUp之后的流程onStartUp方法结束之后tomcat会调用监听器ContextLoaderListener的contextInitialized方法。这个方法中会先加载父容器然后调用它的refesh方法进行刷新。这样service和dao就会被创建到容器中了。之后tomcat会调用DispatcherServlet的init方法。这个方法是在它的父类的父类中定义的init方法会调用initServletBean方法FrameworkServlet中定义。这个方法中会调用initWebApplicationContext实例化子容器并设置parent。之后会调用configureAndRefreshWebApplicationContext方法设置和刷新子容器。这个方法里会设置ContextRefreshListener。之后子容器刷新的最后阶段也就是finishRefresh时会发布ContextRefreshedEvent事件。监听器监听到了之后监听器时FrameworkServlet的内部类就会调用它的onRefresh方法。DS实现了这个方法并且会调用initStrategies也就是在这个方法中完成Springmvc核心组件的初始化。至此SpringMVC的初始化就完成了。为什么Tomcat不会停止tomcat在启动时会创建一些组件这些组件会起一些非守护线程。比如Acceptor线程它会绑定并监听 8080 等端口内部通过一个 while 死循环不断调用 serverSocket.accept()持续阻塞并等待客户端的 HTTP 请求工作线程池用于处理实际的业务请求。这些线程池中的工作线程默认也是非守护线程它们会一直存活以随时处理分发的任务tomcat在初始化所有组件后主线程会调用一个await方法进行阻塞。之后tomcat会创建一个socket去监听8005端口主线程会无限循环等待端口收到一个shutdown的指令。这时才会关闭主线程、关闭容器、最后jvm关闭。
终于把SpringMVC底层看的清清楚楚了!
mvc项目结构启动流程Tomcat启动的时候会去war包中找SpringServletContainerInitializer这个类实例化后调用它的onStartUp方法。这个类有个HandlesTypes({WebApplicationInitializer.class}) 注解。tomcat看到这个注解会去war中找所有的WebApplicationInitializer实现类。并将实现类传给onStartUp方法。之后在这个方法中就会遍历所有的WebApplicationInitializer依次调用它们的onStartUp方法完成web环境初始化。项目中的WebInit类继承了AbstractAnnotationConfigDispatcherServletInitializer这个抽象类其实就是接口实现类。onStartUp的方法流程调用registerContextLoaderListener方法这个方法流程根据WebInit配置类中的getRootConfigClasses方法返回的根容器父容器配置类创建父容器。最终会得到一个AnnotationConfigWebApplicationContext。配置类会存到这个AC的componentClasses属性中。创建一个监听器ContextLoaderListener并放入servletContext由tomcat创建的上下文上面执行完了之后就有了父容器和监听器。现在再根据WebInit中的getServletConfigClasses返回的配置类以同样的流程创建子容器也是一个AnnotationConfigWebApplicationContext。调用createDispatcherServlet创建一个DispatcherServlettomcat的servletContext调用addServlet方法注册DispatcherServletsetLoadOnStartup设置Servlet优先级为1表示容器启动时就立刻初始化DS而不是等第一个请求来了之后懒加载addMapping设置拦截路径可以设置通配符。这个在WebInit的getServletMappings中配置的。为“/”时就是拦截所有请求setAsyncSupported是否支持异步registerServletFilter设置过滤器onStartUp之后的流程onStartUp方法结束之后tomcat会调用监听器ContextLoaderListener的contextInitialized方法。这个方法中会先加载父容器然后调用它的refesh方法进行刷新。这样service和dao就会被创建到容器中了。之后tomcat会调用DispatcherServlet的init方法。这个方法是在它的父类的父类中定义的init方法会调用initServletBean方法FrameworkServlet中定义。这个方法中会调用initWebApplicationContext实例化子容器并设置parent。之后会调用configureAndRefreshWebApplicationContext方法设置和刷新子容器。这个方法里会设置ContextRefreshListener。之后子容器刷新的最后阶段也就是finishRefresh时会发布ContextRefreshedEvent事件。监听器监听到了之后监听器时FrameworkServlet的内部类就会调用它的onRefresh方法。DS实现了这个方法并且会调用initStrategies也就是在这个方法中完成Springmvc核心组件的初始化。至此SpringMVC的初始化就完成了。为什么Tomcat不会停止tomcat在启动时会创建一些组件这些组件会起一些非守护线程。比如Acceptor线程它会绑定并监听 8080 等端口内部通过一个 while 死循环不断调用 serverSocket.accept()持续阻塞并等待客户端的 HTTP 请求工作线程池用于处理实际的业务请求。这些线程池中的工作线程默认也是非守护线程它们会一直存活以随时处理分发的任务tomcat在初始化所有组件后主线程会调用一个await方法进行阻塞。之后tomcat会创建一个socket去监听8005端口主线程会无限循环等待端口收到一个shutdown的指令。这时才会关闭主线程、关闭容器、最后jvm关闭。