背景
由于Spring mvc是在standered servlets
上设计的,并且促进了servlet context
和application context
的相同功能。春天有两种类型的上下文ApplicationContext
和WebApplicationContext
-
ApplicationContext
按ContextLoaderListener
初始化,每个应用程序单个实例。
按WebApplicationContext
加载DispatcherServlet
。
我们可以理解上面这个ApplicationContext
延伸到WebApplicationContext
,所以最后与ApplicationContext
关联的内容最后是WebApplicationContext
的一部分。
质疑
ApplicationContextAware
提供context
对象。
public class SomeThing implements ApplicationContextAware{
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeanException{
//this context object is `ApplicationContext` or `WebApplicationContext`?
}
}
context
和container
似乎是我们大多数人的同义词,我想
举个例子。假设我们有两个调度程序servlet
rest
以及其他mvc
。
第一个调度程序 -
public class RestInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/rest/*" };
}
}
第二个调度程序 -
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected String[] getServletMappings() {
return new String[] { "/mvc/*" };
}
}
这里有WebApplicationContext
的两个实例
公共部分由ContextLoaderListner
加载,如定义中所示
rootContext
。
我不确定,但单个SpringApplication中一定不能有2个IocContainer。
BeanFactory即SpringIocContainer,所有bean对象所在的位置
生活,我们与WebApplicationContext
联系的对象是什么
Spring容器的一部分,这个容器是如何初始化的
WebApplicationContext
?我想知道他们俩是怎么回事
相互联系?
每当我们做ctx.getBean()
时 - 这会从spring返回对象
容器,如何在上下文和容器之间进行通信
会发生什么?
有一个类似的answer否认两者都相同,它说
Spring带有几个容器实现,加载bean定义,连接bean,并根据请求分配bean,但ApplicationContext提供了更多。
所以我的观点是为什么加载bean定义,连接bean,这是一种返工?
即使网络应用程序是弹簧驱动还是没有,还有一个问题,必须有一个standard servlet
在Http通信中提供和使用的上下文......
Spring跟随此或spring以其他方式处理此问题。在spring context
中表示只是IOC container
,其中某些部分由DispacherServlet
加载,而某些部分由ContextLoaderListner
加载I18N
可以提供更多便利,例如access to static resource
,.fix{
border: 1px solid blue;
width: 20%;
display:inline-block;
float:left;
}
.rest{
float: right;
border: 1px solid red;
width:80%;
}
等。
答案 0 :(得分:0)
基本上,在spring MVC应用程序中,spring上下文被注册在Web应用程序的servlet上下文中。您可以在设置spring web.xml
的{{1}}文件或java配置中执行此操作。在评论中我指出了这个链接,它解释了如何通过java配置类完成:
spring: where does `@autowired` look for beans?
在那里你可以看到'连接'是如何完成的。然后,您在评论中询问了这一点:
ContextLoaderListener
如果您检查该类的代码,则可以看到它从WebApplicationContextUtils.getWebApplicationContext(myServlet.getServletContext())
的属性中获取WebApplicationContext
。这些属性在Web应用程序的初始化中设置。如果您注意到ServletContext
类(ContextLoader
的父级),在ContextLoaderListener
方法中它将这些属性设置为servlet上下文:
initWebApplicationContext
这是在这一行完成的:
/**
* Initialize Spring's web application context for the given servlet context,
* using the application context provided at construction time, or creating a new one
* according to the "{@link #CONTEXT_CLASS_PARAM contextClass}" and
* "{@link #CONFIG_LOCATION_PARAM contextConfigLocation}" context-params.
* @param servletContext current servlet context
* @return the new WebApplicationContext
* @see #ContextLoader(WebApplicationContext)
* @see #CONTEXT_CLASS_PARAM
* @see #CONFIG_LOCATION_PARAM
*/
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, etc
if (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);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
}
else if (ccl != null) {
currentContextPerThread.put(ccl, this.context);
}
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
return this.context;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
正如您所看到的,它存储在您尝试使用servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
获取它的位置:
WebApplicationContextUtils.getWebApplicationContext(myServlet.getServletContext())
因此,您可以看到所有疑问的答案都在Spring应用程序启动期间执行的代码中。
希望我回答你的问题。
答案 1 :(得分:0)
怀疑1
在spring应用程序中,有一个上下文实例,WebAplicationCntext
每DispatcherServlet
。这可以通过超级接口引用ApplicationContext
-
public class SomeThing implements ApplicationContextAware{
@Override
public void setApplicationContext(ApplicationContext ctx) throws BeanException{
//this context object is `WebApplicationContext` which is refer by `ApplicationContext`.
}
}
在春天,上下文意味着一个正好的IOC容器,其中一些部分由DispacherServlet加载,一些部分由ContextLoaderListner加载,可以促进更多,如I18N,访问静态资源等 < / p>
您的上述理解几乎是正确的。在Spring中,所有WebApplicationContext
对象都共享一些公共引用rootContext
。
此答案不包括doubt2
,doubt3
和why all context perform same task
的答案。