动态代理实现简单的拦截器

该拦截器需要实现的功能:如果用户已登录那么执行该方法(操作)。如果没有登录,那么拦截该方法(操作),跳转到登录页面。

该拦截器的实现使用JDK的动态代理技术。

需要用到的接口:

public interface Worker {
	void doWork();
}

该接口的实现类:

public class Programmer implements Worker {

	public boolean isLogin;
	@Override
	public void doWork() {
		System.out.println("工作就是写代码");
	}
}

定义拦截器接口:

public interface Interceptor {
	public boolean before(Object proxy,Object target,Method method,Object[] args);
	
	public void around(Object proxy,Object target,Method method,Object[] args);
	
	public void after(Object proxy,Object target,Method method,Object[] args);
}

定义拦截器:

/**
 *模拟登录拦截,若登录,执行该方法。若没有登录,则拦截该方法,跳转到登录页面。
 */
public class MyInterceptor implements Interceptor {

	/**
	 * return true:则执行真实对象的方法
	 * return false: 调用around方法
	 */
	@Override
	public boolean before(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("真实对象的方法执行前");
		System.out.println(target.getClass().getName());
		Programmer programmer=(Programmer)target;
		
		if(programmer.isLogin){
			return true;
		}else{
			return false;
		}
		
	}

	@Override
	public void around(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("取代被代理对象的方法,将真实对象的方法拦截,");
		System.out.println("没有登录,该方法不能执行,正跳转登录页面...");

	}

	/**
	 * 真实对象方法或者around方法执行之后,调用after方法。
	 */
	@Override
	public void after(Object proxy, Object target, Method method, Object[] args) {
		System.out.println("真实对象的方法执行后");

	}
}

动态代理中使用拦截器:
 

public class InterceptorProxyTest implements InvocationHandler {
	//真实对象
	private Object target =null;
	//拦截器的全限定名
	private String interceptorClass=null;
	
	//构造方法
	public InterceptorProxyTest(Object target, String interceptorClass) {
		super();
		this.target = target;
		this.interceptorClass = interceptorClass;
	}

	/**
	 * 
	 * @param target 真实对象,要被代理的
	 * @param interceptorClass 拦截器的全限定名,用于生成拦截器对象
	 * @return 代理对象
	 */
	public static Object bind(Object target,String interceptorClass) {
		
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InterceptorProxyTest(target, interceptorClass));
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		//如果拦截器全限定名为空,那么执行原有对象的方法
		if(interceptorClass==null){
			return method.invoke(target, args);
		}
		Object result=null;
		//通过反射生成拦截器对象
		Interceptor interceptor=(Interceptor)Class.forName(interceptorClass).newInstance();
		
		//调用前置方法
		if(interceptor.before(proxy, target, method, args)){
			//如果before()方法返回真,那么执行原有对象的方法,不拦截
			result=method.invoke(target, args);
		}else{
			//如果before()方法返回false,那么执行around方法,原方法被拦截
			interceptor.around(proxy, args, method, args);
		}
		
		//最后调用after方法。
		interceptor.after(proxy, args, method, args);
		return result;
	}

}

主方法调用:

public class MainClass {

	public static void main(String[] args) {
		Programmer p=new Programmer();
		//设置登录状态为已登录
		p.isLogin=true;
		Worker worker=(Worker) InterceptorProxyTest.bind(p,
				"com.wanLiHong.proxy.inter.MyInterceptor");
		worker.doWork();
	}
}

控制台:

真实对象的方法执行前
com.wanLiHong.proxy.inter.Programmer
工作就是写代码
真实对象的方法执行后

如果将登陆状态设为false,那么执行结果如下:

真实对象的方法执行前
com.wanLiHong.proxy.inter.Programmer
取代被代理对象的方法,将真实对象的方法拦截,
没有登录,该方法不能执行,正跳转登录页面...
真实对象的方法执行后

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值