AOP(Aspect-Oriented Programming,面向切面編程),能夠說是OOP(Object-Oriented Programing,面向對象編程)的補充和完善。OOP利用封裝、繼承和多態把一切事物打形成對象結構,可是對於全部對象中都存在的一些公共行爲,OOP就顯得無能爲力,抽象和接口雖好,但對全部不相干的對象創建共同的接口或父類未免有些生硬,例如日誌功能,日誌代碼幾乎散佈在全部的對象層次中,而它和散佈到對象的核心功能毫無關係,對於其餘類型的代碼,如安全性、異常處理和透明的持續性也是如此。所以,爲減小這種大量的重複代碼,面向切面技術誕生了,AOP和OOP的關係好似JSP和Servlet的關係,以此之長,補彼之短。 html
Java中常見的AOP技術有兩個,分別是Filter和代理模式,代理模式又分爲靜態代理和動態代理。他們各自實現的功能不一樣,原理一模一樣。以下圖,以添加用戶爲例,採用Module1架構模式,從圖中能夠看出不管程序從左向右或者從右向左執行都必須通過Filter,Filter在Request到達JSP(Servlet)前截獲Request並進行預處理,也能夠在Response離開JSP(Servlet)時處理Response,而後對Request進行統一的設置後繼續向後傳遞,好比能夠在Filter完成字符集的設置,用戶身份的識別,敏感詞彙的過濾等等,配置Filter個數不限。 java
下面就以設置字符集爲例,首先建立一個Class文件,並讓他實現Filter接口,覆寫init和doFilter,代碼以下: web
- package com.snail.drp.util.filter;
-
- import java.io.IOException;
-
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
-
- public class CharsetEncodingFilter implements Filter {
- private String endcoding;
-
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- request.setCharacterEncoding(endcoding);
-
- //繼續執行
- chain.doFilter(request, response);
- }
-
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- this.endcoding = filterConfig.getInitParameter("encoding");
- }
- }
- package com.snail.drp.util.filter;
-
- import java.io.IOException;
-
- import javax.servlet.Filter;
- import javax.servlet.FilterChain;
- import javax.servlet.FilterConfig;
- import javax.servlet.ServletException;
- import javax.servlet.ServletRequest;
- import javax.servlet.ServletResponse;
-
- public class CharsetEncodingFilter implements Filter {
- private String endcoding;
-
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
-
- @Override
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain) throws IOException, ServletException {
- request.setCharacterEncoding(endcoding);
-
- //繼續執行
- chain.doFilter(request, response);
- }
-
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- this.endcoding = filterConfig.getInitParameter("encoding");
- }
- }
Filter雖不是一個Servlet,但它須要在web.xml文件中配置以後才能使用,具體解釋看代碼中的註釋,以下: 編程
- <filter>
- <filter-name>CharsetEncodingFilter</filter-name>
- <filter-class>com.snail.drp.util.filter.CharsetEncodingFilter</filter-class>
- <!--在Filter初始化時,設置編碼格式 -->
- <init-param>
- <param-name>encoding</param-name>
- <param-value>GB18030</param-value>
- </init-param>
- </filter>
- <!-- 設置Filter範圍,指對Post請求起做用 -->
- <filter-mapping>
- <filter-name>CharsetEncodingFilter</filter-name>
- <url-pattern>*.jsp</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CharsetEncodingFilter</filter-name>
- <url-pattern>/servlet/*</url-pattern>
- </filter-mapping>
- <filter>
- <filter-name>CharsetEncodingFilter</filter-name>
- <filter-class>com.snail.drp.util.filter.CharsetEncodingFilter</filter-class>
- <!--在Filter初始化時,設置編碼格式 -->
- <init-param>
- <param-name>encoding</param-name>
- <param-value>GB18030</param-value>
- </init-param>
- </filter>
- <!-- 設置Filter範圍,指對Post請求起做用 -->
- <filter-mapping>
- <filter-name>CharsetEncodingFilter</filter-name>
- <url-pattern>*.jsp</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>CharsetEncodingFilter</filter-name>
- <url-pattern>/servlet/*</url-pattern>
- </filter-mapping>
Filter是職責鏈模式的經典應用,從上面示例代碼能夠看出,實現了Filter接口的doFilter方法主要用於截獲Request對象,把截獲的請求處理後(設置字符集),調用FilterChain 接口的chain.doFilter(request,response)方法,把處理權傳遞給下一個filter。 安全
其中,FilterChain維護了一個鏈表,鏈表中存放着配置對象的鏈條,每次用戶調用 一次chain.doFilter(request, response),鏈表就去取下一個配置對象,再經過配置對象 獲得下一個filter,而後調用該filter,接着在filter裏寫的邏輯就被執行了。 架構
http://blog.csdn.net/stubbornpotatoes/article/details/7347663 app