struts2拦截器之动态代理模拟分析

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=======");
	}
}

3.我的动态代理

创建动态代理目标对象,执行目标对象之前调用拦截器方法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;
	}

}

4.动态代理工厂方法

/**
 * 动态代理工厂方法
 */
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);
	}
}

5.拦截器模拟测试

/**
 * 测试拦截器模拟
 */
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=======
不想跑


你可能感兴趣的:(struts2,intercepter,拦截器模拟)