Spring框架AOP部分是基于JDK动态代理和CGLIB动态代理实现的,而JDK动态代理(面向接口)是默认的代理模。
为了后期实现Spring框架的简单模拟,首先完成基于这两种代理机制的拦截器。
先抛开JDK动态代理和CGLIB动态代理的不同,我们在执行invoke方法时都必须用到三个参数:对象、方法、参数。我们首先假设完成了对三个参数的获取。因为考虑到多个拦截器的存在,我们需要创建一个拦截器链IntercepterChain,并采用间接递归的方式走完所有的拦截器(模拟Spring框架的实现方式)。
在此之前,我们需要先创建一个接口:
package com.chy.StringAOP.core;
import java.lang.reflect.Method;
public interface IIntercepter {
// 前置拦截!
boolean before(Object[] args);
// 后置拦截
Object after(Object result);
// 异常处理
void dealException(Throwable e) throws Throwable;
// 判断是不是需要拦截的方法
public boolean isMethod(Method method);
}
下来是通过间接递归实现拦截功能的两个类 :
ProxyInvoker类:
package com.chy.StringAOP.core;
import java.lang.reflect.Method;
public class ProxyInvoker {
private IntercepterChain intercepterChain;
ProxyInvoker() {
intercepterChain = new IntercepterChain(this, null);
}
// 拦截器的添加采用头插的方式
void addIntercepter(IIntercepter intercepter) {
IntercepterChain newChain = new IntercepterChain(this, intercepter);
if (intercepterChain.next == null) {
intercepterChain.next = newChain;
} else {
newChain.next = intercepterChain.next;
intercepterChain.next = newChain;
}
}
// 将拦截器链和截获的参数一同交给doChain()方法执行
// 拦截器放在链域next中
Object invoke(IntercepterChain chain, Object object, Method method, Object[] args)
throws Throwable {
return chain.doChain(chain.getNext(), object, method, args);
}
// 得到参数,并带上拦截器链
Object invoke(Object object, Method method, Object[] args)
throws Throwable{
return invoke(intercepterChain, object, method, args);
}
}
IntercepterChain类:
package com.chy.StringAOP.core;
import java.lang.reflect.Method;
public class IntercepterChain {
IIntercepter intercepter;
ProxyInvoker proxyInvoker;
// 链域
IntercepterChain next;
// proxyInvoker和实现接口的对象作为参数传进来,并完成初始化
IntercepterChain(ProxyInvoker proxyInvoker, IIntercepter intercepter) {
this.proxyInvoker = proxyInvoker;
this.intercepter = intercepter;
this.next = null;
}
IntercepterChain getNext() {
return next;
}
Object doChain(IntercepterChain chain, Object object, Method method, Object[] args)
throws Throwable {
Object result = null;
if (chain != null) {
IIntercepter intercepter = chain.intercepter;
if (intercepter.isMethod(method)
&& intercepter.before(args)) {
try {
// 间接递归,再次执行带有拦截器链的invoke方法,走完整个链将退出
result = proxyInvoker.invoke(chain, object, method, args);
// 每次退出来的执行后置拦截,若无后置拦截,则结果不变
result = intercepter.after(result);
} catch (Throwable e) {
intercepter.dealException(e);
}
} else {
// 若不是需要拦截的方法,或不进行前置拦截,则直接执行
result = method.invoke(object, args);
}
}
return result;
}
}
实现了最重要的部分之后,下来处理JDK动态代理和CGLIB动态代理的不同接收方式和整合。
首先是默认的JDK动态代理:
package com.chy.StringAOP.core;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JDKProxy {
ProxyInvoker chyProxy;
JDKProxy() {
chyProxy = new ProxyInvoker();
}
ProxyInvoker getChyProxy() {
return chyProxy;
}
// 类类型参数处理
<T> T getProxy(Class<?> klass) throws Exception {
Object object = klass.newInstance();
return getProxy(object, klass.getClassLoader(), klass.getInterfaces());
}
// 对象类型参数处理
<T> T getProxy(Object object) {
Class<?> klass = object.getClass();
return getProxy(object, klass.getClassLoader(), klass.getInterfaces());
}
@SuppressWarnings("unchecked")
private <T> T getProxy(Object object, ClassLoader classLoader, Class<?>[] interfaces) {
return (T) Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return chyProxy.invoke(object, method, args);
}
});
}
}
CGLIB动态代理的处理:
package com.chy.StringAOP.core;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibProxy {
ProxyInvoker chyProxy;
CglibProxy() {
chyProxy = new ProxyInvoker();
}
<T> T getProxy(Object object) {
return getProxy(object.getClass(), object);
}
<T> T getProxy(Class<?> klass) throws Exception {
return getProxy(klass, klass.newInstance());
}
@SuppressWarnings("unchecked")
private <T> T getProxy(Class<?> klass, Object object) {
try {
// 通过参数类型的所有构造器,判断是否有可操作的参数
Constructor<?> constructor =
klass.getDeclaredConstructor(new Class<?>[] {});
int modifiers = constructor.getModifiers();
if ((modifiers & Modifier.PRIVATE) != 0) {
return (T) object;
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(klass);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
// TODO 预留操作,从BeanFactory()中获取ProxyInvoker对象
return chyProxy.invoke(object, method, args);
}
});
return (T) enhancer.create();
}
}
整合:
package com.chy.StringAOP.core;
public class ChyProxy {
public static final int CGLIB_PROXY = 1;
public static final int JDK_PROXY = 2;
protected int proxyType;
// 默认为JDK代理
public ChyProxy() {
proxyType = JDK_PROXY;
}
public void setProxyType(int type) {
this.proxyType = type;
}
public <T> T getProxy(Class<?> klass) throws Exception {
if (CGLIB_PROXY == proxyType
|| klass.getInterfaces().length <= 0) {
return new CglibProxy().getProxy(klass);
}
return new JDKProxy().getProxy(klass);
}
public <T> T getProxy(Object object) {
if (CGLIB_PROXY == proxyType
|| object.getClass().getInterfaces().length <= 0) {
return new CglibProxy().getProxy(object);
}
return new JDKProxy().getProxy(object);
}
}