SpringMVC父子容器加载与关系源码
来源:互联网 发布:安卓慢镜头软件 编辑:程序博客网 时间:2024/06/15 20:18
我们都知道SpringMVC父子容器加载是通过dispatcherServlet与ContextLoaderListener类:他们的关系源码如下:
先说父容器加载:Context'Loader'Listener源码如下:
@Overridepublic void contextInitialized(ServletContextEvent event) {initWebApplicationContext(event.getServletContext());}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {throw new IllegalStateException("Cannot initialize context because there is already a root application context present - " +"check whether you have multiple ContextLoader* definitions in your web.xml!");}Log logger = LogFactory.getLog(ContextLoader.class);servletContext.log("Initializing Spring root WebApplicationContext");if (logger.isInfoEnabled()) {logger.info("Root WebApplicationContext: initialization started");}long startTime = System.currentTimeMillis();try {// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.if (this.context == null) {this.context = createWebApplicationContext(servletContext);}if (this.context instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent ->// determine parent for root web application context, if any.ApplicationContext parent = loadParentContext(servletContext);cwac.setParent(parent);}configureAndRefreshWebApplicationContext(cwac, servletContext);}}servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);加红这两行是重点,我们看到它把父容器加载的context放入了servletContext的一个属性中,这个属性的值如下:
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";后面我们看看DispatcherServlet的加载ApplicationContext的方式:
DispatcherServlet有一个父类是HttpServletBean进入它的init方法:public final void init() throws ServletException {if (logger.isDebugEnabled()) {logger.debug("Initializing servlet '" + getServletName() + "'");}// Set bean properties from init parameters.try {PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));initBeanWrapper(bw);bw.setPropertyValues(pvs, true);}catch (BeansException ex) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);throw ex;}// Let subclasses do whatever initialization they like.initServletBean();if (logger.isDebugEnabled()) {logger.debug("Servlet '" + getServletName() + "' configured successfully");}}
protected final void initServletBean() throws ServletException {getServletContext().log("Initializing Spring FrameworkServlet '" + getServletName() + "'");if (this.logger.isInfoEnabled()) {this.logger.info("FrameworkServlet '" + getServletName() + "': initialization started");}long startTime = System.currentTimeMillis();try {this.webApplicationContext = initWebApplicationContext();
protected WebApplicationContext initWebApplicationContext() {WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;if (this.webApplicationContext != null) {// A context instance was injected at construction time -> use itwac = this.webApplicationContext;if (wac instanceof ConfigurableWebApplicationContext) {ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;if (!cwac.isActive()) {// The context has not yet been refreshed -> provide services such as// setting the parent context, setting the application context id, etcif (cwac.getParent() == null) {// The context instance was injected without an explicit parent -> set// the root application context (if any; may be null) as the parentcwac.setParent(rootContext);}configureAndRefreshWebApplicationContext(cwac);}}}
我们看到子容器里面放了rootContext父容器,那么这个父容器是不是就是ContextLoaderListener加载的context的呢,我们看下第一行标红的代码:WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());
public static WebApplicationContext getWebApplicationContext(ServletContext sc) { return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); }public interface WebApplicationContext extends ApplicationContext { String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
我们发现这个放入的值与我们ContextLoaderListener放入父容器中的值一样,说明子容器的rootContext就是我们之前放入的父容器。
阅读全文
0 0
- SpringMVC父子容器加载与关系源码
- Spring 与 SpringMVC 容器父子关系引出的相应问题
- Spring与SpringMVC父子容器
- Spring和springmvc父子容器关系
- springmvc和spring的父子容器关系
- Spring、SpringMVC父子容器关系浅析
- spring和springmvc父子容器的关系
- spring和springmvc父子容器关系
- spring和springmvc父子容器的关系
- Spring和SpringMVC 父子容器关系
- Springmvc和spring的父子容器关系
- spring和springmvc父子容器的关系
- Spring和SpringMVC父子容器关系
- spring和springmvc的父子容器关系
- Spring 与 SpringMVC 父子容器问题
- springMVC容器加载源码分析
- spring 和 springmvc 的父子容器关系浅析
- Spring和SpringMVC父子容器关系初窥
- codevs 1098 均分纸牌
- JAVA任务标记
- 属性动画 组合跳转界面
- 统计学习方法——第四章朴素贝叶斯
- BZOJ 3790 神奇项链
- SpringMVC父子容器加载与关系源码
- 【java】Guava缓存值CacheBuilder学习
- svn 服务配置,创建文件
- CSS3(2)
- 前端jq-MD5加密 + js-base64加密
- UVA 816 Abbott's Revenge BFS求最短路+路径输出(详细注释)
- liunx 内存释放
- nutz自定义sql查询
- 多目标跟踪的简单理解