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