由于动态代理较难理解,可以设计一个拦截器来实现代理。只需要知道拦截器接口的方法、含义、作用即可。
这里实现一个拦截器,然后在jdk代理中使用拦截器实现jdk动态代理。
代理还是要有两个步骤:1、建立代理对象和真实对象的关系; 2、实现代理逻辑。
这里的1建立关系还是在jdk代理类中实现,而2代理逻辑则是放在了拦截器实现类中,jdk代理类只是调用拦截器方法。
拦截器接口:
package ssm.interceptor;
import java.lang.reflect.Method;
public interface Interceptor {
/**
* 返回 boolean值, 在真实对象前调用
* 返回true时,反射真实对象的方法
* false时,调用around方法
* @param proxy 代理对象
* @param target 真实对象
* @param method 方法
* @param args 方法参数
* @return
*/
public boolean before(Object proxy, Object target, Method method, Object[] args);
/*
返回false时,调用
*/
public void around(Object proxy, Object target, Method method, Object[] args);
/*
反射真实方法或around方法之后,调用after方法
*/
public void after(Object proxy, Object target, Method method, Object[] args);
}
拦截器实现类:
package ssm.interceptor;
import java.lang.reflect.Method;
public class MyInterceptor implements Interceptor {
@Override
public boolean before(Object proxy, Object target, Method method, Object[] args) {
System.out.println("反射方法前逻辑");
return false;
}
@Override
public void around(Object proxy, Object target, Method method, Object[] args) {
System.err.println("反射方法后逻辑");
}
@Override
public void after(Object proxy, Object target, Method method, Object[] args) {
System.out.println("取代了被代理对象的方法");
}
}
jdk代理中使用拦截器:
package ssm.interceptor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class InterceprotJdkProxy implements InvocationHandler {
//真实对象
private Object target;
//拦截器全限定名
private String interceptorClass = null;
/*
这里多个构造函数,实现上就是为了在下面函数第三个参数中,起到this的作用
*/
public InterceprotJdkProxy(Object target, String interceptorClass){
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 InterceprotJdkProxy(target, interceptorClass));
}
/**
* 通过代理对象调用方法,首先进入这个方法
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@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)){
result = method.invoke(target, args);
}else{
interceptor.around(proxy, target, method, args);
}
interceptor.after(proxy, target, method, args);
return null;
}
}