springmvc启动入口,springmvc部署
springmv的核心入口类是什么
springmvc的入口是servlet,而struts2是filter(这里要指出,filter和servlet是不同的。以前认为filter是servlet的一种特殊),这样就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,参数的传递是直接注入到方法中的,是该方法独有的。struts2是类级别的拦截,一个类对应一个request上下文,struts是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的,这也就无法用注解或其他方式标识其所属方法了。
Spring5MVC——启动过程,执行refresh方法的入口
在容器初始化时会建立所有url和controller的对应关系,保存到Mapurl,controller中。tomcat启动时会通知spring初始化容器(加载bean的定义信息和初始化所有单例bean),然后springmvc会遍历容器中的bean,获取每一个controller中的所有方法访问的url,然后将url和Controller保存到一个Map中。
这样就可以根据request快速定位到Controller,因为最终处理request的是Controller中的方法,Map中只保留了url和Controller中的对应关系,所以要根据request的url进一步确认Controller中的method,这一步工作的原理就是拼接Controller的url(Controller上@RequestMapping的值)和方法的url(method上@RequestMapping的值),与request的url进行匹配,找到匹配的那个方法。
确定处理请求的method后,接下来的任务就是参数绑定,把request中参数绑定到方法的形式参数上,这一步是整个请求处理过程中最复杂的一个步骤。SpringMVC提供了两种request参数与方法形参的绑定方法:
* ① 通过注解进行绑定 @RequestParam
* ② 通过参数名称进行绑定
使用注解进行绑定,我们只要在方法参数前面声明@RequestParam("a"),就可以将request中参数a的值绑定到方法的该参数上。使用参数名称进行绑定的前提是必须要获取方法中参数的名称,Java反射只提供了获取方法的参数的类型,并没有提供获取参数名称的方法。SpringMVC解决这个问题的方法是用asm框架读取字节码文件,来获取方法的参数名称。asm框架是一个字节码操作框架,关于asm更多介绍可以参考它的官网。个人建议,使用注解来完成参数绑定,这样就可以省去asm框架的读取字节码的操作。
这意味着注解配置方式的初始化会先于web.xml配置方式的初始化执行,并且在执行到这里的时候,Spring里面相关的Root容器、子容器和DispatcherServlet实例都已经被创建好了。
HttpServlet是Servlet规范中的核心类,实现Servlet接口,继承此类用于处理用户请求
HttpServletBean主要配置servlet中初始化参数。继承HttpServlet,并实现无参的init()方法,用于设置在web.xml中配置的contextConfigLocation属性,此属性指定Spring MVC的配置文件地址,默认为WEB-INF/[servlet-name]-servlet.xml。
HttpServletBean的作用:
FrameworkServlet主要创建WebApplicationContext上下文,重写了HttpServletBean的initServletBean()方法。
如果没有WebApplicationContext则创建
总结FrameworkServlet的作用:
DispatcherServlet是Spring MVC核心,它是J2EE规范前端控制器的实现,负责拦截用户请求,并解析请求进行转发。
总结:
参考:
spring mvc 为什么要以servlet为入口
servlet充当了核心控制器,所以核心是DispatcherServlet服务启动的时候要注册这个入口,否则就会报错
一、spring是咋启动的
spring是咋启动的
? ?????? 对于应用程序来说,spring的启动是没有什么好说的,直接运行main方法,通过new GenericXmlApplicationContext、ClassPathXmlApplicationContext、XmlBeanFactory等这些容器类,会自动解析xml配置,然后自动进行bean的注入、初始化等,而我们最终也可以从容器中提取这些类,进行各种各样的操作。
?????? 对于web程序来说,并不是直接用main方式调用spring容器进行启动的,而都是以tomcat方式进行启动的,那么tomcat是怎么解析spring的xml配置,怎么进行bean的初始化、注入的呢?
?????? tomcat其实也是一个main程序。它启动后,调用spring的配置文件的过程如下:
StandContext.startInternal()àStandContext.listenerStart()àContextLoadListener.contextInitialized()àAbstractApplicationContext.refresh().
ContextLoadListener实现了ServletContextListener,因此会调用ContextLoadListener的contextInitialized()方法。
这样就很明了了吧, refresh方法正是spring进行xml解析、bean注入、ioc、aop等等方法的入口。? tomcat会把ServletContextEvent传递给spring, even中有servletContext,这个context也构造出spring的context。最后通过refresh完成大部分的构建、初始化工作。
那么对于springMvc是怎么启动的呢?springMvc的配置文件? spring-servlet.xml是如何解析的呢?
同样还是在tomcat的loadOnStartup()方法中,对大于等于0的servelet进行了调用。
StandardContext.startInternal()àloadOnStartup()àStandardWrapper.load()àload()àloadServlet()àinitServlet()àDispatcherServlet.init()àFrameworkServlet.initServletBean()àrefresh()。? 这里加载的是springMvc的配置文件
为什么说springMvc是spring的子容器?
因为spring的配置加载后,然后对DispatcherServlet 进行初始化,最后对springMvc的配置解析是存放在DispatcherServlet 的父类FrameworkServlet 中的webApplicationContext属性容器中。其中在initWebApplicationContext()方法中,通过在ServletContext也即ApplicationContext中set进去的属性“ ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE ”,获取到rootContext,rootContext是前面spring解析出来的容器,setParent(),在webApplicationContext设置父容器rootContext,? 通过rootContext然后构建出webApplicationContext。也就是说springMvc是获得到了spring的容器。
子容器可以获取到父容器的内容,而父容器获取不到子容器的内容。
"favlis\5x??