该拦截器需要实现的功能:如果用户已登录那么执行该方法(操作)。如果没有登录,那么拦截该方法(操作),跳转到登录页面。
该拦截器的实现使用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
取代被代理对象的方法,将真实对象的方法拦截,
没有登录,该方法不能执行,正跳转登录页面...
真实对象的方法执行后