美文网首页
2021-12-16 Spring中父子容器的创建

2021-12-16 Spring中父子容器的创建

作者: 归去来ming | 来源:发表于2021-12-16 11:09 被阅读0次

1,父容器的创建

// ContextLoaderListener
@Override
public void contextInitialized(ServletContextEvent event) {
    initWebApplicationContext(event.getServletContext());
}
/**
ContextLoader的initWebApplicationContext方法
这里为什么要判断instanceof ConfigurableWebApplicationContext ?
因为默认创建的是XmlWebApplicationContext,平常写Demo经常用到的
ClassPathXmlApplicationContext类和FileSystemXmlApplicationContext类
不属于这个类的子类或实现类
*/
if (this.context == null) {
    this.context = createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)this.context;
    if (!cwac.isActive()) {
        if (cwac.getParent() == null) {
            // loadParentContext方法默认返回的也是null
            ApplicationContext parent = this.loadParentContext(servletContext);
            cwac.setParent(parent);
        }

        this.configureAndRefreshWebApplicationContext(cwac, servletContext);
    }
}
从这张类图上可以清晰看到,只有XmlWebApplicationContext是ConfigurableWebApplicationContext的实现类,而ClassPathXmlApplicationContext和FileSystemXmlApplicationContext不是。 image.png

实际上ConfigurableWebApplicationContext有多个子类或实现类:


image.png

2,子容器的创建

// FrameworkServlet
protected WebApplicationContext initWebApplicationContext() {
    // 父容器
    WebApplicationContext rootContext =
            WebApplicationContextUtils.getWebApplicationContext(getServletContext());
    // 子容器
    WebApplicationContext wac = null;
      // FrameworkServlet构造函数创建了webApplicationContext,见AbstractDispatcherServletInitializer类
    if (this.webApplicationContext != null) {
        // A context instance was injected at construction time -> use it
        wac = 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, etc
                if (cwac.getParent() == null) {
                    // The context instance was injected without an explicit parent -> set
                    // the root application context (if any; may be null) as the parent
                    // 设置父子容器关系
                    cwac.setParent(rootContext);
                }
                configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }
    if (wac == null) {
        // No context instance was injected at construction time -> see if one
        // has been registered in the servlet context. If one exists, it is assumed
        // that the parent context (if any) has already been set and that the
        // user has performed any initialization such as setting the context id
        wac = findWebApplicationContext();
    }
    if (wac == null) {
        // No context instance is defined for this servlet -> create a local one
        wac = createWebApplicationContext(rootContext);
    }

    if (!this.refreshEventReceived) {
        // Either the context is not a ConfigurableApplicationContext with refresh
        // support or the context injected at construction time had already been
        // refreshed -> trigger initial onRefresh manually here.
        onRefresh(wac);
    }

    if (this.publishContext) {
        // Publish the context as a servlet context attribute.
        String attrName = getServletContextAttributeName();
        getServletContext().setAttribute(attrName, wac);
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Published WebApplicationContext of servlet '" + getServletName() +
                    "' as ServletContext attribute with name [" + attrName + "]");
        }
    }

    return wac;
}
图片.png
// AbstractDispatcherServletInitializer
protected FrameworkServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
   return new DispatcherServlet(servletAppContext);
}

相关文章

  • 2021-12-16 Spring中父子容器的创建

    1,父容器的创建 从这张类图上可以清晰看到,只有XmlWebApplicationContext是Configur...

  • Spring 学习笔记(二):Spring 容器以及 bean

    Spring 容器 在 Spring 应用中,应用对象生存于 Spring 容器中,Spring 容器负责创建对象...

  • spring 学习02

    Spring 容器 在Spring 应用中,你的应用对象生存在Spring容器中,Spring 容器负责创建对象,...

  • spring的父子容器及配置

    spring父子容器 spring总的上下文容器有父子之分,父容器和子容器。** 父容器对子容器可见,子容器对父容...

  • 扫盲--Spring启动和父子容器问题

    背景 做Spring项目时,会存在父子容器的问题,当然,你不创建ContextLoaderListener,只使用...

  • spring的父子上下文容器及配置

    本文由作者张远道授权网易云社区发布。 spring父子容器 spring总的上下文容器有父子之分。父容器和子容器。...

  • spring的父子上下文容器及配置

    本文由作者张远道授权网易云社区发布。 spring父子容器 spring总的上下文容器有父子之分。父容器和子容器。...

  • spring中的父子容器

    Spring中的父子容器 背景 在很长的一段时间里面,关于Spring父子容器这个问题我一直没太关注,但是上次同事...

  • 3.Spring容器

    这篇文章主要介绍Spring中的容器在Spring中也同样存在容器,而且Spring的容器是负责创建对象,装配be...

  • 容器

    在基于Spring的应用中,你的应用对象生存于Spring容器(container)中。Spring容器负责创建对...

网友评论

      本文标题:2021-12-16 Spring中父子容器的创建

      本文链接:https://www.haomeiwen.com/subject/nttvfrtx.html