平常的子类继承父类通过extends
关键字来实现,那么Spring父容器与Spring MVC子容器是如何体现出父子关系的呢?
容器指的是一个类吗?Spring容器是哪个类,Spring MVC容器又是哪个类?
平常的子类继承父类通过extends
关键字来实现,那么Spring父容器与Spring MVC子容器是如何体现出父子关系的呢?
容器指的是一个类吗?Spring容器是哪个类,Spring MVC容器又是哪个类?
想必Servlet的关系就不必多说了,直接上代码吧HttpServletBean
继承了 HttpServlet
,init方法如下
@Override
public final void init() throws ServletException {
// Let subclasses do whatever initialization they like.
initServletBean();
}
看看子类FrameworkServlet#initServletBean
方法
@Override
protected final void initServletBean() throws ServletException {
this.webApplicationContext = initWebApplicationContext();
initFrameworkServlet();
}
看看 initWebApplicationContext
protected WebApplicationContext initWebApplicationContext() {
WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());
WebApplicationContext wac = null;
if (this.webApplicationContext != null) {
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 ,看到没有,如果有就设置rootApplicationContext,
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. 看到这里就不多说了,初始化beanFactory
onRefresh(wac);
}
if (this.publishContext) {
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
结束,就是辣么简单
3 回答2.6k 阅读✓ 已解决
3 回答4.1k 阅读✓ 已解决
8 回答3.6k 阅读
4 回答2.8k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
3 回答1.7k 阅读✓ 已解决
所谓容器,就是上下文,在这同一个上下文里,大家可以共享一些东西。
在
Spring
应用启动时,会先读取web.xml
文件,调用ContextLoaderListener
创建Spring
容器,也就是你说的父容器。Listener创建完之后,开始创建Servlet:
这时候这个
DispatcherServlet
开始试图创建SpringMVC
的ApplicationContext
,它先找刚才由上面那个ContextLoaderListener
创建的Spring
的ApplicationContext
,找到后,把Spring
的ApplicationContext
作为参数传给DispatcherServlet
的ApplicationContext
的setParent
方法,这样SpringMVC
的容器就变成了Spring
容器的儿子。因为在SpringMVC这个子容器创建的时候指定了它的Spring父容器,所以儿子能找到父亲,所以SpringMVC这个子容器里的Bean可以调用父容器的服务,而父容器不知道有这个儿子的存在(一个不负责任的父亲),父容器里的Bean不能调用子容器里的服务。