We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
之前分析了过 Spring 的启动过程了,今天看下 SpringMVC 的启动。一样的,我们先看下 web.xml,SpringMVC 是以 Servlet 配置出现的
<context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:spring-application.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
之前分析了 ContextLoaderListener,实例化 IoC 容器,并将此容器实例注册到 ServletContext 中。我们先看下 DispatcherServlet 的类图及继承关系:
SpringMVC最核心的类就是 DispatcherServlet, 关于 Spring Context 的配置文件加载和创建是在 init() 方法中进行的,主要的调用顺序是 init-->initServletBean-->initWebApplicationContext 。 先来看一下 initWebApplicationContext 的实现:FrameworkServlet.java
先简单说下这些代码的功能: 514行:从 ServletContext 中获取 rootContext也就是SpringIOC容器 517行:如果一个 context 的实例被注入了,直接使用 538行:从 ServletContext 中获取 webApplicationContext也就是SpringMVC容器 543行:创建 SpringMVC 的容器,并将 rootContext 作为父容器 550行:刷新上下文(执行组件的初始化),这个方法由子类DispatchServlet的方法实现 556行:将 SpringMVC 容器作为属性设置进 ServletContext 这里多说一句,SpringMVC 容器在 ServletContext 中的属性名:
public String getServletContextAttributeName() { return SERVLET_CONTEXT_PREFIX + getServletName(); } public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT.";
而 SpringIOC 容器在 ServletContext 中的属性名:
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
前面的没什么好说的,我们看下 onRefresh() 方法,调用了 initStrategies() 方法:
执行 MVC 的相关组件的初始化,我们以 HandlerMappings 为例看来看下:
detectAllHandlerMappings 默认为 true,从当前的 SpringMVC 容器及其父容器中查找所有的 HandlerMappings,否则只从当前的 SpringMVC 容器中查找 HandlerMapping,如果没有找到 handlerMappings,设置默认的 handlerMapping,默认值设置在 DispatcherServlet 同级目录的 DispatcherServlet.properties 中。
上面的 findWebApplicationContext(),createWebApplicationContext(rootContext) 之类的方法点进去看看也很容易懂,我就不贴源码了,然后 createWebApplicationContext 中会层层调用直到 AbstractApplicationContext的 refresh 方法来初始化 bean,这个方法在之前分析 Spring 启动的时候看过,这里也就不看了。
还是那句话,以我现在水平分析源码并不指望能看懂并理解每一句每一行,但是看不懂的方法你就点进去看看,万一里面里面的东西你看过呢是不是,就怕看不懂然后觉得这行代码不重要就不看了。
嗯?说完了?怎么感觉看完之前的Spring容器那点事,再看这个好像也没什么了。我们再来简单说下 Spring 容器和 SpringMVC 容器的py(手动滑稽)关系。
ContextLoaderListener 中创建 ApplicationContext(SpringIOC容器)主要用于整个 Web 应用程序需要共享的一些组件 ,比如 DAO,数据库的 ConnectionFactory 等。而由 DispatcherServlet 创建的 ApplicationContext(SpringMVC容器)主要用于和该 Servlet 相关的一些组件 ,比如 Controller、ViewResovler 等。
对于作用范围而言, 在 DispatcherServlet 中可以引用由 ContextLoaderListener 所创建的 ApplicationContext ,而反过来不行。 在 Spring 的具体实现上,这两个 ApplicationContext 都是通过 ServletContext 的 setAttribute 方法放到 ServletContext 中的。但是, ContextLoaderListener 会先于 DispatcherServlet 创建 ApplicationContext,DispatcherServlet 在创建 ApplicationContext 时会先找到由 ContextLoaderListener 所创建的 ApplicationContext,再将后者的 ApplicationContext 作为参数传给 DispatcherServlet 的 ApplicationContext 的 setParent() 方法,
wac.setParent(parent);
其中, wac 即为由 DisptcherServlet 创建的 ApplicationContext,而 parent 则为 ContextLoaderListener 创建的ApplicationContext 。此后,框架又会调用 ServletContext 的 setAttribute() 方法将 wac 加入到 ServletContext 中。
当 Spring 在执行 ApplicationContext 的 getBean 时, 如果在自己 context 中找不到对应的 bean,则会在父容器中去找 。这也解释了为什么我们可以在 DispatcherServlet 中获取到由 ContextLoaderListener 对应的 ApplicationContext 中的 bean。举个例子就是,你可以在 controller 层中注入 service 层的 bean。
The text was updated successfully, but these errors were encountered:
😌
Sorry, something went wrong.
No branches or pull requests
SpringMVC容器
之前分析了过 Spring 的启动过程了,今天看下 SpringMVC 的启动。一样的,我们先看下 web.xml,SpringMVC 是以 Servlet 配置出现的
之前分析了 ContextLoaderListener,实例化 IoC 容器,并将此容器实例注册到 ServletContext 中。我们先看下 DispatcherServlet 的类图及继承关系:
SpringMVC最核心的类就是 DispatcherServlet, 关于 Spring Context 的配置文件加载和创建是在 init() 方法中进行的,主要的调用顺序是 init-->initServletBean-->initWebApplicationContext 。 先来看一下 initWebApplicationContext 的实现:FrameworkServlet.java
先简单说下这些代码的功能:
514行:从 ServletContext 中获取 rootContext也就是SpringIOC容器
517行:如果一个 context 的实例被注入了,直接使用
538行:从 ServletContext 中获取 webApplicationContext也就是SpringMVC容器
543行:创建 SpringMVC 的容器,并将 rootContext 作为父容器
550行:刷新上下文(执行组件的初始化),这个方法由子类DispatchServlet的方法实现
556行:将 SpringMVC 容器作为属性设置进 ServletContext
这里多说一句,SpringMVC 容器在 ServletContext 中的属性名:
而 SpringIOC 容器在 ServletContext 中的属性名:
前面的没什么好说的,我们看下 onRefresh() 方法,调用了 initStrategies() 方法:
执行 MVC 的相关组件的初始化,我们以 HandlerMappings 为例看来看下:
detectAllHandlerMappings 默认为 true,从当前的 SpringMVC 容器及其父容器中查找所有的 HandlerMappings,否则只从当前的 SpringMVC 容器中查找 HandlerMapping,如果没有找到 handlerMappings,设置默认的 handlerMapping,默认值设置在 DispatcherServlet 同级目录的 DispatcherServlet.properties 中。
多说一句
上面的 findWebApplicationContext(),createWebApplicationContext(rootContext) 之类的方法点进去看看也很容易懂,我就不贴源码了,然后 createWebApplicationContext 中会层层调用直到 AbstractApplicationContext的 refresh 方法来初始化 bean,这个方法在之前分析 Spring 启动的时候看过,这里也就不看了。
还是那句话,以我现在水平分析源码并不指望能看懂并理解每一句每一行,但是看不懂的方法你就点进去看看,万一里面里面的东西你看过呢是不是,就怕看不懂然后觉得这行代码不重要就不看了。
嗯?说完了?怎么感觉看完之前的Spring容器那点事,再看这个好像也没什么了。我们再来简单说下 Spring 容器和 SpringMVC 容器的py(手动滑稽)关系。
Spring容器 和 SpringMVC容器的关系
ContextLoaderListener 中创建 ApplicationContext(SpringIOC容器)主要用于整个 Web 应用程序需要共享的一些组件 ,比如 DAO,数据库的 ConnectionFactory 等。而由 DispatcherServlet 创建的 ApplicationContext(SpringMVC容器)主要用于和该 Servlet 相关的一些组件 ,比如 Controller、ViewResovler 等。
对于作用范围而言, 在 DispatcherServlet 中可以引用由 ContextLoaderListener 所创建的 ApplicationContext ,而反过来不行。
在 Spring 的具体实现上,这两个 ApplicationContext 都是通过 ServletContext 的 setAttribute 方法放到 ServletContext 中的。但是, ContextLoaderListener 会先于 DispatcherServlet 创建 ApplicationContext,DispatcherServlet 在创建 ApplicationContext 时会先找到由 ContextLoaderListener 所创建的 ApplicationContext,再将后者的 ApplicationContext 作为参数传给 DispatcherServlet 的 ApplicationContext 的 setParent() 方法,
其中, wac 即为由 DisptcherServlet 创建的 ApplicationContext,而 parent 则为 ContextLoaderListener 创建的ApplicationContext 。此后,框架又会调用 ServletContext 的 setAttribute() 方法将 wac 加入到 ServletContext 中。
当 Spring 在执行 ApplicationContext 的 getBean 时, 如果在自己 context 中找不到对应的 bean,则会在父容器中去找 。这也解释了为什么我们可以在 DispatcherServlet 中获取到由 ContextLoaderListener 对应的 ApplicationContext 中的 bean。举个例子就是,你可以在 controller 层中注入 service 层的 bean。
The text was updated successfully, but these errors were encountered: