<%@ taglib uri="
<c:redirect url="home.htm"/> 請求的分發(fā) 請求首先到達DispatcherServlet,應(yīng)用服務(wù)器會根據(jù)Web應(yīng)用中web.xml文件定義的url映射將相應(yīng)的請求分發(fā)到DispatcherServlet中 請求的處理 DispatcherServlet會查找相應(yīng)的HandlerMapping接口的實現(xiàn)類,調(diào)用其中的方法:HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception,該方法會返回一個HandlerExecutionChain。返回的HandlerExecutionChain中包含了零個或者是多個Interceptor和一個處理請求的Handler。DispatcherServlet會調(diào)用Interceptor中的preHandle() 方法。然后處理Handler,這個Handler相當于Struts中Action,在SpringMVC中默認的實現(xiàn)是Controller接口,是具體處理請求的代碼所駐留的地方。事實上HandlerExecutionChain中的getHandler()返回的是一個Object類型。DispatcherServlet不會直接調(diào)用getHandler()返回對象中的方法,DispatcherServlet會查找相應(yīng)的HandlerAdapter,然后具體通過HandlerAdapter來調(diào)用getHandler()返回的handler對象中的方法。就是說我們可以實現(xiàn)自己的HandlerAdapter然后通過IoC注入到DispatcherServlet中,從而可以實現(xiàn)一套自定義的控制器。隨后DispatcherServlet會調(diào)用Interceptor中的postHandle()方法。 視圖的處理 DispatcherServlet會期望Hander返回一個ModelAndView,DispatcherServlet會根據(jù)所返回的ModelAndView對象所包含的信息進行視圖的渲染。起具體出來流程如下: 首先DispatcherServlet會根據(jù)LocaleResolver來識別請求中的Locale,開發(fā)人員可以自己實現(xiàn)LocaleResolver接口,然后通過IoC注入到DispatcherServlet中,然后DispatcherServlet會判斷ModelAndView中是否已經(jīng)包含了接口View的具體實現(xiàn),如果包含了,則直接調(diào)用View中的方法render(Map model, HttpServletRequest request, HttpServletResponse response)。如果不包含,則說明該ModelAndView只是包含了View的名稱引用,DispatcherServlet會調(diào)用ViewResolver中的resolveViewName(String viewName, Locale locale)來解析其真正的視圖。該方法會返回一個View的具體實現(xiàn)。 視圖的渲染 Spring支持多種視圖技術(shù),其中比較常用的包括有Jstl視圖,Veloctiy視圖,F(xiàn)reeMarker視圖等。對Jstl視圖的渲染Spring是通過JstlView這個類具體實現(xiàn)的。事實上其最終的渲染是交給容器來做的,Spring只是通過RequestDispatcher實現(xiàn)了服務(wù)器內(nèi)部請求的Forward。而對于模板視圖,如Veloctiy和FreeMarker等,Spring會初始化其相應(yīng)的模板引擎,由模板引擎生成最終的Html頁面然后在合并到Response的輸出流中。 異常的處理 如果在Hander中處理請求是拋出異常,DispatcherServlet會查找HandlerExceptionResolver接口的具體實現(xiàn),該接口定義了一個方法: ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex),實現(xiàn)類需要實現(xiàn)該方法以便對異常進行處理,最后該方法需要返回一個ModelAndView。 SpringMVC的一些總結(jié) Simple extension of HttpServlet的簡單擴展用來處理 (init-param)in the web.xml This servlet leaves request handling to subclasses, inheriting the default behavior of HttpServlet ( This generic servlet base class has no dependency on the Spring The Base servlet for Spring's web framework. Provides integration with a Spring application context, in a JavaBean-based overall solution. spring web Framework的基礎(chǔ) servlet? ,提供在以javabean為基礎(chǔ)的整體解決方案已完成與spring應(yīng)用上下文的集成 Subclasses must implement 因為它繼承自httpservletBean 所以bean的屬性已經(jīng)被自動的裝配了,子類可以通過覆蓋initFrameworkServlet來定制初始化bean Passes a "contextConfigLocation" servlet init-param to the context instance, parsing it into potentially multiple file paths which can be separated by any number of commas and spaces, like "test-servlet.xml, myServlet.xml". If not explicitly specified, the context implementation is supposed to build a default location from the namespace of the servlet. Note: In case of multiple config locations, later bean definitions will override ones defined in earlier loaded files, at least when using Spring's default ApplicationContext implementation. This can be leveraged to deliberately override certain bean definitions via an extra XML file. The default namespace is "'servlet-name'-servlet", e.g. "test-servlet" for a servlet-name "test" (leading to a "/WEB-INF/test-servlet.xml" default location with XmlWebApplicationContext). The namespace can also be set explicitly via the "namespace" servlet init-param.
<c:redirect url="b.jsp">
<c:param name="data" value="jsp_passdata中文傳值"></c:param>
</c:redirect>
他們兩個作用相似
<jsp:forward page="/utils/errorReporter.jsp"/>
<jsp:forward page="/test4.jsp">
<jsp:param name="name" value="powerman"/>
<jsp:param name="address" value=" 北京西大街188號"/>
</jsp:forward><fmt:requestEncoding value="big5"/>
靈活的Interceptor,通過Interceptor我們可以在一個請求處理前和請求處理完成之后做相應(yīng)的操作,通過Interceptor機制,我們可以做authentication, logging, and filtering等。
良好的表單支持,在SpringMVC的Controller繼承體系結(jié)構(gòu)中,其具體的子類對表單(Form)提供了良好的支持。能夠很好的支持單個表單的顯示、修改、提交操作。同時也提供了表單的分步提交。
可定制的數(shù)據(jù)綁定(Data Binding)。
多視圖技術(shù)的支持,SpringMVC同時支持Jstl, Velocity 等多中視圖技術(shù),但是這同時也會引出一個問題,因為各種視圖技術(shù)都有自己的一套方法來處理國際化,例如Jstl和Velocity處理國際化的方式就很不相同。因此在多個視圖技術(shù)并存的應(yīng)用中,國際化也是一個需要注意的問題。
其Handler(控制器)作為Bean定義在Spring容器中,因此能享受容器帶來的服務(wù)。
Handler(控制器)具有良好的可測試性。
public abstract class HttpServletBean
HttpServlet
which treats its config parameters (init-param
entries within the servlet
tag in web.xml
) as bean properties.
A handy superclass for any type of servlet. Type conversion of config parameters is automatic, with the corresponding setter method getting invoked with the converted value. It is also possible for subclasses to specify required properties. Parameters without matching bean property setter will simply be ignored. doGet
, doPost
, etc). ApplicationContext
concept. Simple servlets usually don't load their own context but rather access service beans from the Spring root application context, accessible via the filter's ServletContext
(see WebApplicationContextUtils
). FrameworkServlet
class is a more specific servlet base class which loads its own application context. FrameworkServlet serves as direct base class of Spring's full-fledged DispatcherServlet
.
public abstract class FrameworkServlet
This class offers the following functionality:
1.管理一個servlet一個網(wǎng)絡(luò)應(yīng)用上下文實例,這個servlet的配置由servlet命名空間里的bean來決定
2.根據(jù)請求處理發(fā)布事件,是否請求成功的被處理了
WebApplicationContext
instance per servlet. The servlet's configuration is determined by beans in the servlet's namespace.
doService(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
to handle requests. Because this extends HttpServletBean
rather than HttpServlet directly, bean properties are automatically mapped onto it. Subclasses can override initFrameworkServlet()
for custom initialization.
Detects a "contextClass" parameter at the servlet init-param level, falling back to the default context class, XmlWebApplicationContext
, if not found. Note that, with the default FrameworkServlet, a custom context class needs to implement the ConfigurableWebApplicationContext
SPI.
Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:<bean id="exampleInitBean" class="examples.ExampleBean" init-method="cleanup"/>
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
BeanFactory的實現(xiàn)應(yīng)該盡可能支持標準的bean生命周期,以下是所以的方法的順序的依次列表
1. BeanNameAware's?? setBeanName
2. BeanClassLoaderAware's? setBeanClassLoader
3. BeanFactoryAware's?? setBeanFactory
4. ResourceLoaderAware's setResourceLoader
(only applicable when running in an application context)
5. ApplicationEventPublisherAware's setApplicationEventPublisher
(only applicable when running in an application context)
6. MessageSourceAware's setMessageSource
(only applicable when running in an application context)
7. ApplicationContextAware's setApplicationContext
(only applicable when running in an application context)
8. ServletContextAware's setServletContext
(only applicable when running in a web application context)
9. postProcessBeforeInitialization
methods of BeanPostProcessors
10. InitializingBean's afterPropertiesSet
11. a custom init-method definition
12. postProcessAfterInitialization
methods of BeanPostProcessors
?當關(guān)閉一個bean的時候
On shutdown of a bean factory, the following lifecycle methods apply:
1. DisposableBean's destroy
2. a custom destroy-method definition
Method Summary | |
---|---|
?boolean | containsBean(String?name) ??????????Does this bean factory contain a bean with the given name? |
?String[] | getAliases(String?name) ??????????Return the aliases for the given bean name, if any. |
?Object | getBean(String?name) ??????????Return an instance, which may be shared or independent, of the specified bean. |
?Object | getBean(String?name, Class?requiredType) ??????????Return an instance, which may be shared or independent, of the specified bean. |
?Class | getType(String?name) ??????????Determine the type of the bean with the given name. |
?boolean | isPrototype(String?name) ??????????Is this bean a prototype? |
?boolean | isSingleton(String?name) ??????????Is this bean a shared singleton? |
?boolean | isTypeMatch(String?name, Class?targetType) ??????????Check whether the bean with the given name matches the specified type. |
public interface Lifecycle
Interface defining methods for start/stop lifecycle control. The typical use case for this is to control asynchronous processing.
Can be implemented by both components (typically a Spring bean defined in a Spring BeanFactory
) and containers (typically a Spring ApplicationContext
). Containers will propagate start/stop signals to all components that apply.
Can be used for direct invocations or for management operations via JMX. In the latter case, the MBeanExporter
will typically be defined with an InterfaceBasedMBeanInfoAssembler
, restricting the visibility of activity-controlled components to the Lifecycle interface.
ConfigurableApplicationContext
, AbstractMessageListenerContainer
, SchedulerFactoryBean
Method Summary | |
---|---|
?boolean
|
isRunning
()
??????????Check whether this component is currently running. |
?void
|
start
()
??????????Start this component. |
?void
|
stop
()
??????????Stop this component. |
Spring中Bean的生命周期 | |||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%5p] %d{HH:mm:ss} %c{1} - %m%n
log4j.rootLogger=WARN, stdout
log4j.category.com.springinaction=DEBUG
log4j.category.org.springframework=WARN
package com.springinaction.chapter01.knight;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice;
public class MinstrelAdvice implements MethodBeforeAdvice {
? public void before(Method method, Object[] args, Object target)
????? throws Throwable {
??? Knight knight = (Knight) target;
???
??? Logger song = Logger.getLogger(target.getClass());
???
??? song.debug("Brave " + knight.getName() + " did " + method.getName());
? }
}
package com.springinaction.chapter01.knight;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.FileSystemResource;
public class KnightApp {
? private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger
????? .getLogger(KnightApp.class);
?
? public static void main(String[] args) throws Exception {
??? LOGGER.debug("Running KnightApp");
??? ApplicationContext m;
??? BeanFactory factory =
??????? new XmlBeanFactory(new FileSystemResource("knight.xml"));
///有XmlBeanFactory來負責具體的實現(xiàn)???? knight.xml必須要保存在項目的總目錄下面
Knight knight =
??????? (Knight) factory.getBean("knight");
??? knight.embarkOnQuest();
??? System.out.println("ok");
??? LOGGER.debug("KnightApp Finished");
? }
}
?Spring中ApplicationContext加載機制。
????? ??? 加載器目前有兩種選擇:ContextLoaderListener和ContextLoaderServlet。
???????? 這兩者在功能上完全等同,只是一個是基于Servlet2.3版本中新引入的Listener接口實現(xiàn),而另一個基于Servlet接口實現(xiàn)。開發(fā)中可根據(jù)目標Web容器的實際情況進行選擇。
配置非常簡單,在web.xml中增加:
<listener>
? <listener-class>
?????? org.springframework.web.context.ContextLoaderListener
? </listener-class>
</listener>
或:
<servlet>
??? <servlet-name>context</servlet-name>
??? <servlet-class>
?????? org.springframework.web.context.ContextLoaderServlet
??? </servlet-class>
??? <load-on-startup>1</load-on-startup>
</servlet>?
?
????????? 通過以上配置,Web容器會自動加載/WEB-INF/applicationContext.xml初始化
ApplicationContext實例,如果需要指定配置文件位置,可通過context-param加以指定:
<context-param>
??? <param-name>contextConfigLocation</param-name>
??? <param-value>/WEB-INF/myApplicationContext.xml</param-value>
</context-param>
??????? 配置完成之后,即可通過
?WebApplicationContextUtils.getWebApplicationContext方法在Web應(yīng)用中獲取ApplicationContext引用。
如:ApplicationContext ctx=WebApplicationContextUtils.getWebApplicationContext();
??? LoginAction action=(LoginAction)ctx.getBean("action");