程序设计者设计拦截器供开发者使用,开发者只需要知道拦截器接口的方法、含义和作用即可,无需知道动态代理是怎么实现的。
拦截器接口Interceptor
package com.lucas;
import java.lang.reflect.Method;
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);
}
方法说明:
before:返回true,反射真实对象的方法
around:before返回false,调用的方法
after:在反射真实对象方法或around方法之后调用的方法
Interceptor的实现类:
package com.lucas;
import java.lang.reflect.Method;
public class MyInterceptor implements Interceptor{
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("反射方法前逻辑");
return false;//不反射被代理原有方法
}
public void around(Object proxy, Object target, Method method, Object[] args) {
System.out.println("取代了被代理对象的方法");
}
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("反射方法后逻辑");
}
}
jdk动态代理中使用拦截器:
package com.lucas;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InterceptorJdkProxy implements InvocationHandler {
private Object target; //真实对象
private String interceptorClass = null; //拦截器全限定名
public InterceptorJdkProxy(Object target, String interceptorClass) {
this.target = target;
this.interceptorClass = interceptorClass;
}
public static Object bind(Object target, String interceptorClass) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InterceptorJdkProxy(target,interceptorClass));
}
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)) {
result = method.invoke(target,args);
} else {
interceptor.around(proxy,target,method,args);
}
interceptor.after(proxy,target,method,args);
return result;
}
public static void main(String[] args) {
HelloWord proxy = (HelloWord) InterceptorJdkProxy.bind(new HelloWorldImpl(), "com.lucas.MyInterceptor");
proxy.sayHello();
}
}
运行结果:
反射方法前逻辑
取代了被代理对象的方法
反射方法后逻辑
开发者只需要知道拦截器的作用就可以编写拦截器了,编写完之后可以设置拦截器,这样就完成了任务,所以对开发者来说就相对简单了
设计者可能是精通java的开发人员,他完成动态代理的逻辑
设计者只会把拦截器接口暴露给开发者使用,让动态代理的逻辑在开发者的视野里消失