- 浏览: 44783 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
Booill:
请问BO可以跨域登录么
sap BusinessObjects 4 java 单点登录处理 sso -
greemranqq:
jar 用不起,不能识别 为什么呢
sap BusinessObjects 4 java 单点登录处理 sso -
lei_jingjun:
tomcat 启动就报错 是jar冲突吗 ?
sap BusinessObjects 4 java 单点登录处理 sso -
lei_jingjun:
sap BusinessObjects 4.0 SP4 用 ...
sap BusinessObjects 4 java 单点登录处理 sso
以下引用自博客:http://jiwenke-spring.blogspot.com/
上面我们分析了IOC容器本身的实现,下面我们看看在典型的web环境中,Spring IOC容器是怎样被载入和起作用的。
简单的说,在web容器中,通过ServletContext为Spring的IOC容器提供宿主环境,对应的建立起一个IOC容器的体系。其中,首先需要建立的是根上下文,这个上下文持有的对象可以有业务对象,数据存取对象,资源,事物管理器等各种中间层对象。在这个上下文的基础上,和web MVC相关还会有一个上下文来保存控制器之类的MVC对象,这样就构成了一个层次化的上下文结构。在web容器中启动Spring应用程序就是一个建立这个上下文体系的过程。Spring为web应用提供了上下文的扩展接口
WebApplicationContext:
Java代码
1.public interface WebApplicationContext extends ApplicationContext {
2. //这里定义的常量用于在ServletContext中存取根上下文
3. String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
4. ......
5. //对WebApplicationContext来说,需要得到Web容器的ServletContext
6. ServletContext getServletContext();
7.}
public interface WebApplicationContext extends ApplicationContext {
//这里定义的常量用于在ServletContext中存取根上下文
String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";
......
//对WebApplicationContext来说,需要得到Web容器的ServletContext
ServletContext getServletContext();
}
而一般的启动过程,Spring会使用一个默认的实现,XmlWebApplicationContext - 这个上下文实现作为在web容器中的根上下文容器被建立起来,具体的建立过程在下面我们会详细分析。
Java代码
1.public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
2.
3. /** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/
4. public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
5. public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
6. public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
7.
8. //我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。
9. protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
10. //对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析
11. XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
12.
13. beanDefinitionReader.setResourceLoader(this);
14. beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
15.
16. initBeanDefinitionReader(beanDefinitionReader);
17. loadBeanDefinitions(beanDefinitionReader);
18. }
19.
20. protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
21. }
22. //使用XmlBeanDefinitionReader来读入bean定义信息
23. protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
24. String[] configLocations = getConfigLocations();
25. if (configLocations != null) {
26. for (int i = 0; i < configLocations.length; i++) {
27. reader.loadBeanDefinitions(configLocations[i]);
28. }
29. }
30. }
31. //这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml
32. protected String[] getDefaultConfigLocations() {
33. if (getNamespace() != null) {
34. return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
35. }
36. else {
37. return new String[] {DEFAULT_CONFIG_LOCATION};
38. }
39. }
40.}
public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
/** 这是和web部署相关的位置信息,用来作为默认的根上下文bean定义信息的存放位置*/
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
//我们又看到了熟悉的loadBeanDefinition,就像我们前面对IOC容器的分析中一样,这个加载工程在容器的refresh()的时候启动。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException {
//对于XmlWebApplicationContext,当然使用的是XmlBeanDefinitionReader来对bean定义信息来进行解析
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protected void initBeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
}
//使用XmlBeanDefinitionReader来读入bean定义信息
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (int i = 0; i < configLocations.length; i++) {
reader.loadBeanDefinitions(configLocations[i]);
}
}
}
//这里取得bean定义信息位置,默认的地方是/WEB-INF/applicationContext.xml
protected String[] getDefaultConfigLocations() {
if (getNamespace() != null) {
return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
}
else {
return new String[] {DEFAULT_CONFIG_LOCATION};
}
}
}
对于一个Spring激活的web应用程序,可以通过使用Spring代码声明式的指定在web应用程序启动时载入应用程序上下文(WebApplicationContext),Spring的ContextLoader是提供这样性能的类,我们可以使用 ContextLoaderServlet或者ContextLoaderListener的启动时载入的Servlet来实例化Spring IOC容器 - 为什么会有两个不同的类来装载它呢,这是因为它们的使用需要区别不同的Servlet容器支持的Serlvet版本。但不管是 ContextLoaderSevlet还是 ContextLoaderListener都使用ContextLoader来完成实际的WebApplicationContext的初始化工作。这个ContextLoder就像是Spring Web应用程序在Web容器中的加载器booter。当然这些Servlet的具体使用我们都要借助web容器中的部署描述符来进行相关的定义。
下面我们使用ContextLoaderListener作为载入器作一个详细的分析,这个Servlet的监听器是根上下文被载入的地方,也是整个 Spring web应用加载上下文的第一个地方;从加载过程我们可以看到,首先从Servlet事件中得到ServletContext,然后可以读到配置好的在web.xml的中的各个属性值,然后ContextLoder实例化WebApplicationContext并完成其载入和初始化作为根上下文。当这个根上下文被载入后,它被绑定到web应用程序的ServletContext上。任何需要访问该ApplicationContext的应用程序代码都可以从WebApplicationContextUtils类的静态方法来得到:
Java代码
1.WebApplicationContext getWebApplicationContext(ServletContext sc)
WebApplicationContext getWebApplicationContext(ServletContext sc)
以Tomcat作为Servlet容器为例,下面是具体的步骤:
1.Tomcat 启动时需要从web.xml中读取启动参数,在web.xml中我们需要对ContextLoaderListener进行配置,对于在web应用启动入口是在ContextLoaderListener中的初始化部分;从Spring MVC上看,实际上在web容器中维护了一系列的IOC容器,其中在ContextLoader中载入的IOC容器作为根上下文而存在于 ServletContext中。
Java代码
1.//这里对根上下文进行初始化。
2.public void contextInitialized(ServletContextEvent event) {
3. //这里创建需要的ContextLoader
4. this.contextLoader = createContextLoader();
5. //这里使用ContextLoader对根上下文进行载入和初始化
6. this.contextLoader.initWebApplicationContext(event.getServletContext());
7.}
//这里对根上下文进行初始化。
public void contextInitialized(ServletContextEvent event) {
//这里创建需要的ContextLoader
this.contextLoader = createContextLoader();
//这里使用ContextLoader对根上下文进行载入和初始化
this.contextLoader.initWebApplicationContext(event.getServletContext());
}
通过ContextLoader建立起根上下文的过程,我们可以在ContextLoader中看到:
Java代码
1.public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
2. throws IllegalStateException, BeansException {
3. //这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。
4. if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
5. //直接抛出异常
6. .........
7. }
8.
9. ...............
10. try {
11. // 这里载入根上下文的父上下文
12. ApplicationContext parent = loadParentContext(servletContext);
13.
14. //这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是
15. //ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文
16. this.context = createWebApplicationContext(servletContext, parent);
17. servletContext.setAttribute(
18. WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
19. ..........
20.
21. return this.context;
22. }
23. ............
24.}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext)
throws IllegalStateException, BeansException {
//这里先看看是不是已经在ServletContext中存在上下文,如果有说明前面已经被载入过,或者是配置文件有错误。
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
//直接抛出异常
.........
}
...............
try {
// 这里载入根上下文的父上下文
ApplicationContext parent = loadParentContext(servletContext);
//这里创建根上下文作为整个应用的上下文同时把它存到ServletContext中去,注意这里使用的ServletContext的属性值是
//ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,以后的应用都是根据这个属性值来取得根上下文的 - 往往作为自己上下文的父上下文
this.context = createWebApplicationContext(servletContext, parent);
servletContext.setAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
..........
return this.context;
}
............
}
建立根上下文的父上下文使用的是下面的代码,取决于在web.xml中定义的参数:locatorFactorySelector,这是一个可选参数:
Java代码
1.protected ApplicationContext loadParentContext(ServletContext servletContext)
2. throws BeansException {
3.
4. ApplicationContext parentContext = null;
5.
6. String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
7. String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
8.
9. if (locatorFactorySelector != null) {
10. BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
11. ........
12. //得到根上下文的父上下文的引用
13. this.parentContextRef = locator.useBeanFactory(parentContextKey);
14. //这里建立得到根上下文的父上下文
15. parentContext = (ApplicationContext) this.parentContextRef.getFactory();
16. }
17.
18. return parentContext;
19.}
protected ApplicationContext loadParentContext(ServletContext servletContext)
throws BeansException {
ApplicationContext parentContext = null;
String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);
String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);
if (locatorFactorySelector != null) {
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector);
........
//得到根上下文的父上下文的引用
this.parentContextRef = locator.useBeanFactory(parentContextKey);
//这里建立得到根上下文的父上下文
parentContext = (ApplicationContext) this.parentContextRef.getFactory();
}
return parentContext;
}
得到根上下文的父上下文以后,就是根上下文的创建过程:
Java代码
1.protected WebApplicationContext createWebApplicationContext(
2. ServletContext servletContext, ApplicationContext parent) throws BeansException {
3. //这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext,
4. //如果没有使用默认的。
5. Class contextClass = determineContextClass(servletContext);
6. .........
7. //这里就是上下文的创建过程
8. ConfigurableWebApplicationContext wac =
9. (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
10. //这里保持对父上下文和ServletContext的引用到根上下文中
11. wac.setParent(parent);
12. wac.setServletContext(servletContext);
13.
14. //这里从web.xml中取得相关的初始化参数
15. String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
16. if (configLocation != null) {
17. wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
18. ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
19. }
20. //这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。
21. wac.refresh();
22. return wac;
23.}
protected WebApplicationContext createWebApplicationContext(
ServletContext servletContext, ApplicationContext parent) throws BeansException {
//这里需要确定我们载入的根WebApplication的类型,由在web.xml中配置的contextClass中配置的参数可以决定我们需要载入什么样的ApplicationContext,
//如果没有使用默认的。
Class contextClass = determineContextClass(servletContext);
.........
//这里就是上下文的创建过程
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
//这里保持对父上下文和ServletContext的引用到根上下文中
wac.setParent(parent);
wac.setServletContext(servletContext);
//这里从web.xml中取得相关的初始化参数
String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
if (configLocation != null) {
wac.setConfigLocations(StringUtils.tokenizeToStringArray(configLocation,
ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
//这里对WebApplicationContext进行初始化,我们又看到了熟悉的refresh调用。
wac.refresh();
return wac;
}
初始化根ApplicationContext后将其存储到SevletContext中去以后,这样就建立了一个全局的关于整个应用的上下文。这个根上下文会被以后的DispatcherServlet初始化自己的时候作为自己ApplicationContext的父上下文。这个在对 DispatcherServlet做分析的时候我们可以看看到。
3.完成对ContextLoaderListener的初始化以后, Tomcat开始初始化DispatchServlet,- 还记得我们在web.xml中队载入次序进行了定义。DispatcherServlet会建立自己的ApplicationContext,同时建立这个自己的上下文的时候会从ServletContext中得到根上下文作为父上下文,然后再对自己的上下文进行初始化,并最后存到 ServletContext中去供以后检索和使用。
可以从DispatchServlet的父类FrameworkServlet的代码中看到大致的初始化过程,整个ApplicationContext的创建过程和ContextLoder创建的过程相类似:
Java代码
1.protected final void initServletBean() throws ServletException, BeansException {
2. .........
3. try {
4. //这里是对上下文的初始化过程。
5. this.webApplicationContext = initWebApplicationContext();
6. //在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素
7. initFrameworkServlet();
8. }
9. ........
10.}
protected final void initServletBean() throws ServletException, BeansException {
.........
try {
//这里是对上下文的初始化过程。
this.webApplicationContext = initWebApplicationContext();
//在完成对上下文的初始化过程结束后,根据bean配置信息建立MVC框架的各个主要元素
initFrameworkServlet();
}
........
}
对initWebApplicationContext()调用的代码如下:
Java代码
1.protected WebApplicationContext initWebApplicationContext() throws BeansException {
2. //这里调用WebApplicationContextUtils静态类来得到根上下文
3. WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
4.
5. //创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
6. WebApplicationContext wac = createWebApplicationContext(parent);
7. ........
8. if (isPublishContext()) {
9. //把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。
10. String attrName = getServletContextAttributeName();
11. getServletContext().setAttribute(attrName, wac);
12. }
13. return wac;
14.}
protected WebApplicationContext initWebApplicationContext() throws BeansException {
//这里调用WebApplicationContextUtils静态类来得到根上下文
WebApplicationContext parent = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
//创建当前DispatcherServlet的上下文,其上下文种类使用默认的在FrameworkServlet定义好的:DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class;
WebApplicationContext wac = createWebApplicationContext(parent);
........
if (isPublishContext()) {
//把当前建立的上下文存到ServletContext中去,注意使用的属性名是和当前Servlet名相关的。
String attrName = getServletContextAttributeName();
getServletContext().setAttribute(attrName, wac);
}
return wac;
}
其中我们看到调用了WebApplicationContextUtils的静态方法得到根ApplicationContext:
Java代码
1. public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
2. //很简单,直接从ServletContext中通过属性名得到根上下文
3. Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
4. .......
5. return (WebApplicationContext) attr;
6. }
7.然后创建DispatcherServlet自己的WebApplicationContext:
8. protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
9. throws BeansException {
10. .......
11. //这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS =
12. //XmlWebApplicationContext.class;
13. ConfigurableWebApplicationContext wac =
14. (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
15.
16. //这里配置父上下文,就是在ContextLoader中建立的根上下文
17. wac.setParent(parent);
18.
19. //保留ServletContext的引用和相关的配置信息。
20. wac.setServletContext(getServletContext());
21. wac.setServletConfig(getServletConfig());
22. wac.setNamespace(getNamespace());
23.
24. //这里得到ApplicationContext配置文件的位置
25. if (getContextConfigLocation() != null) {
26. wac.setConfigLocations(
27. StringUtils.tokenizeToStringArray(
28. getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
29. }
30.
31. //这里调用ApplicationContext的初始化过程,同样需要使用refresh()
32. wac.refresh();
33. return wac;
34. }
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
//很简单,直接从ServletContext中通过属性名得到根上下文
Object attr = sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
.......
return (WebApplicationContext) attr;
}
然后创建DispatcherServlet自己的WebApplicationContext:
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent)
throws BeansException {
.......
//这里使用了BeanUtils直接得到WebApplicationContext,ContextClass是前面定义好的DEFAULT_CONTEXT_CLASS =
//XmlWebApplicationContext.class;
ConfigurableWebApplicationContext wac =
(ConfigurableWebApplicationContext) BeanUtils.instantiateClass(getContextClass());
//这里配置父上下文,就是在ContextLoader中建立的根上下文
wac.setParent(parent);
//保留ServletContext的引用和相关的配置信息。
wac.setServletContext(getServletContext());
wac.setServletConfig(getServletConfig());
wac.setNamespace(getNamespace());
//这里得到ApplicationContext配置文件的位置
if (getContextConfigLocation() != null) {
wac.setConfigLocations(
StringUtils.tokenizeToStringArray(
getContextConfigLocation(), ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
//这里调用ApplicationContext的初始化过程,同样需要使用refresh()
wac.refresh();
return wac;
}
4. 然后就是DispatchServlet中对Spring MVC的配置过程,首先对配置文件中的定义元素进行配置 - 请注意这个时候我们的WebApplicationContext已经建立起来了,也意味着DispatcherServlet有自己的定义资源,可以需要从web.xml中读取bean的配置信息,通常我们会使用单独的xml文件来配置MVC中各个要素定义,这里和web容器相关的加载过程实际上已经完成了,下面的处理和普通的Spring应用程序的编写没有什么太大的差别,我们先看看MVC的初始化过程:
Java代码
1.protected void initFrameworkServlet() throws ServletException, BeansException {
2. initMultipartResolver();
3. initLocaleResolver();
4. initThemeResolver();
5. initHandlerMappings();
6. initHandlerAdapters();
7. initHandlerExceptionResolvers();
8. initRequestToViewNameTranslator();
9. initViewResolvers();
10.}
protected void initFrameworkServlet() throws ServletException, BeansException {
initMultipartResolver();
initLocaleResolver();
initThemeResolver();
initHandlerMappings();
initHandlerAdapters();
initHandlerExceptionResolvers();
initRequestToViewNameTranslator();
initViewResolvers();
}
5. 这样MVC的框架就建立起来了,DispatchServlet对接受到的HTTP Request进行分发处理由doService()完成,具体的MVC处理过程我们在doDispatch()中完成,其中包括使用Command模式建立执行链,显示模型数据等,这些处理我们都可以在DispatcherServlet的代码中看到:
Java代码
1.protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
2. ......
3. try {
4. doDispatch(request, response);
5. }
6. .......
7.}
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
......
try {
doDispatch(request, response);
}
.......
}
实际的请求分发由doDispatch(request,response)来完成:
Java代码
1.protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception {
2. .......
3. // 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。
4. HandlerExecutionChain mappedHandler = null;
5.
6. ......
7. try {
8. //我们熟悉的ModelAndView在这里出现了。
9. ModelAndView mv = null;
10. try {
11. processedRequest = checkMultipart(request);
12.
13. //这里更具request中的参数和映射关系定义决定使用的handler
14. mappedHandler = getHandler(processedRequest, false);
15.
16. ......
17. //这里是handler的调用过程,类似于Command模式中的execute.
18. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
19. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
20.
21. .......
22. //这里将模型数据通过视图进行展现
23. if (mv != null && !mv.wasCleared()) {
24. render(mv, processedRequest, response);
25. }
26. ........
27. }
protected void doDispatch(final HttpServletRequest request, HttpServletResponse response) throws Exception {
.......
// 这是Spring定义的执行链,里面放了映射关系对应的handler和定义的相关拦截器。
HandlerExecutionChain mappedHandler = null;
......
try {
//我们熟悉的ModelAndView在这里出现了。
ModelAndView mv = null;
try {
processedRequest = checkMultipart(request);
//这里更具request中的参数和映射关系定义决定使用的handler
mappedHandler = getHandler(processedRequest, false);
......
//这里是handler的调用过程,类似于Command模式中的execute.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
.......
//这里将模型数据通过视图进行展现
if (mv != null && !mv.wasCleared()) {
render(mv, processedRequest, response);
}
........
}
这样具体的MVC模型的实现就由bean配置文件里定义好的view resolver,handler这些类来实现用户代码的功能。
总结上面的过程,我们看到在web容器中,ServletContext可以持有一系列的web上下文,而在整个web上下文中存在一个根上下文来作为其它 Servlet上下文的父上下文。这个根上下文是由ContextLoader载入并进行初始化的,对于我们的web应用, DispatcherSerlvet载入并初始化自己的上下文,这个上下文的父上下文是根上下文,并且我们也能从ServletContext中根据 Servlet的名字来检索到我们需要的对应于这个Servlet的上下文,但是根上下文的名字是由Spring唯一确定的。这个 DispactcherServlet建立的上下文就是我们开发Spring MVC应用的IOC容器。
具体的web请求处理在上下文体系建立完成以后由DispactcherServlet来完成,上面对MVC的运作做了一个大致的描述,下面我们会具体就SpringMVC的框架实现作一个详细的分析。
相关推荐
当我们在Web环境中运行Spring应用时,IoC容器需要在Web容器(如Tomcat、Jetty等)中启动并运行。这个过程涉及到一系列的初始化步骤,确保Spring能够正确地与Web容器集成。 首先,`WebApplicationContext`是`...
总结来说,Spring IOC容器在Web容器中的启动涉及到创建`WebApplicationContext`,加载配置文件中的bean定义,然后通过`refresh()`方法实例化和初始化bean。这个过程确保了Web应用程序能够正确地配置和运行其依赖的...
在Spring源代码解析的第一部分,我们将聚焦于IOC容器,特别是BeanFactory接口,它是所有Spring容器的基础。 BeanFactory接口是Spring的基石,它定义了基本的容器操作,如获取Bean、检查Bean是否存在、确定Bean的...
标题 "Spring3.1.3 Ioc在Web容器中的建立" 涉及的是Spring框架的一个关键特性——依赖注入(Dependency Injection,简称DI),以及如何在Web应用环境中配置和使用它。Spring是Java开发中最流行的轻量级框架之一,...
总结,MVC与IOC容器的结合在Formwork框架中实现了高度的模块化和解耦,使得开发者能够更专注于业务逻辑,而不是对象的创建和管理。通过依赖注入,降低了组件间的耦合,增强了代码的可读性和可测试性,为项目的开发和...
在探讨Spring 3.X企业应用开发过程中,第四章的内容聚焦于如何在Spring框架的核心组件——IoC(控制反转)容器中装配Bean。在Spring框架中,Bean装配是指Spring容器将应用程序中的对象进行实例化、配置以及组装的...
### Spring IoC容器部署实现详解 #### 一、Spring IoC容器概述 Spring框架的核心特性之一就是Inversion of Control(IoC),也被称为Dependency Injection(DI)。IoC容器是Spring框架的重要组成部分,它负责管理...
本篇文章将深入探讨Spring实现原理,阐述IoC容器的优点,并指导如何在Eclipse中创建一个Spring的Web应用。 首先,让我们理解Spring的核心——IoC容器。IoC是一种设计模式,它改变了对象获取依赖的方式。在传统的...
- **配置**:在web.xml文件中添加简单的XML描述符即可实例化Spring IoC容器,无需编写额外的Java代码。 - **示例**:参考Section3.8.4,“ApplicationContext在WEB应用中的实例化”。 #### 五、总结 通过本章的...
- **Web应用**:在Spring MVC中,Controller层的bean通过IoC容器管理,方便进行依赖注入和AOP增强。 总之,Spring IoC容器作为核心组件,极大地提高了软件设计的灵活性和可维护性,通过解耦和管理对象的生命周期,...
"001_通过默认ICO容器和自定义实现类的实例化操作_Web"表明这个压缩包的内容可能是一个教程或示例项目,展示了如何在Web环境中利用Spring IoC容器来管理对象的生命周期和依赖关系,同时涉及到了自定义实现类的实例化...
在软件设计中,控制反转是一种设计原则,它将对象的控制权从对象本身转移到外部容器中,从而实现了对象之间的松耦合。 在基于IOC容器实现管理mybatis过程解析中,IOC容器扮演着核心角色。IOC容器可以管理mybatis的...
在Web应用程序中,IOC容器的初始化是通过DispatcherServlet的onRefresh()方法来完成的。在onRefresh()方法中,会调用initStrategies()方法来初始化SpringMVC的九大组件。initStrategies()方法会初始化诸如...
在Spring框架中,IoC容器是核心组件,它负责创建、装配和管理对象。IoC容器通过读取XML配置文件来理解对象及其依赖关系,然后自动进行实例化和装配。这样,开发者不再需要手动创建和管理对象,而是将这些控制权交给...
ListableBeanFactory接口在ApplicationContext中定义,允许我们查询容器中所有Bean的定义信息。WebApplicationContext是专门为Web应用设计的ApplicationContext子接口,它提供与Servlet环境集成的方法,如获取...
这一步至关重要,因为`ContextLoaderListener`负责在应用启动时加载Spring的配置文件,建立并初始化Spring IoC容器。配置示例如下: ```xml org.springframework.web.context.ContextLoaderListener ``` ...
可以在XML文件中配置这些实例,其详细信息如下:Web服务地址,类型(用于Web资源的SOAP,REST或HTTP之一),超时和用于构建请求对象以及从结果到响应对象的转换的算法。 对Web服务的调用以对API客户端透明的通用...
在C#中,通常通过接口和抽象类来实现依赖注入,同时可以利用微软的Unity、Autofac或Ninject等第三方IOC容器来简化这一过程。IOC容器负责解析依赖关系,根据配置自动创建对象并注入到其他对象中,使得代码更加灵活。 ...