struts2拦截器是struts2非常重要的一部分,采用AOP(面向切面编程)设计哲学,动态拦截action请求,在action执行前后插入代码,基于软件代码复用的原则。
大部分时候,拦截器方法是通过动态代理调用的,以jdk动态代理模拟调用拦截器方法。
1.动态代理目标对象
定义接口,提供实现类,生成动态代理对象必备条件。
public interface Pig { //info方法声明 public void info(); //run方法声明 public void run(); }
public class PigImpl implements Pig { @Override public void info() { // TODO Auto-generated method stub System.out.println("我是懒猪"); } @Override public void run() { // TODO Auto-generated method stub System.out.println("不想跑"); } }2.模拟定义拦截器
系统用于拦截Pig实例的拦截器类定义,一个普通的java类。
/** * 模拟定义拦截器 */ public class PigIntercepter { //第一个拦截器方法 public void method1(){ System.out.println("=========模拟通用方法1======="); } //第二个拦截器方法 public void method2(){ System.out.println("=========模拟通用方法2======="); } }
创建动态代理目标对象,执行目标对象之前调用拦截器方法1,之后调用拦截器方法2,正符合AOP编程思想,从而实现拦截的功能,
实质就是执行Pig这个目标对象之前执行PigIntercepter第一方法,之后执行PigIntercepter的第二个方法,实现拦截的功能。
struts2在处理action时,通过类似原理,拦截器把访问action生成动态代理,执行action前后,插入代码,最后执行action对应目标方法,返回视图。
/** * 动态代理自定义 */ public class ProxyHandler implements InvocationHandler{ //需要被代理的目标对象 private Object target; //创建拦截器实例 PigIntercepter di = new PigIntercepter(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub Object result = null; if (method.getName().equals("info")) { //调用拦截器方法1 di.method1(); result = method.invoke(target, args); //调用拦截器方法2 di.method2(); } else { result = method.invoke(target, args); } return result; } //设置传入目标对象 public void setTarget(Object target) { this.target = target; } }
/** * 动态代理工厂方法 */ public class MyProxyFactory { public static Object getProxy(Object object){ //代理的处理类 ProxyHandler handler = new ProxyHandler(); //把dog实例托付给代理操作 handler.setTarget(object); return Proxy.newProxyInstance(PigImpl.class.getClassLoader(), object.getClass().getInterfaces(), handler); } }
/** * 测试拦截器模拟 */ public class TestPig { public static void main(String[] args){ //创建一个Dog实例,即将被用于代理的目标对象 Pig targetObject = new PigImpl(); Pig pig = null; //以目标对象创建代理 Object proxy = MyProxyFactory.getProxy(targetObject); if (proxy instanceof Pig) { pig = (Pig)proxy; } //测试代理方法 pig.info(); pig.run(); } }6.执行结果
=========模拟通用方法1=======
我是懒猪
=========模拟通用方法2=======
不想跑