一、 jdk动态代理
直接上代码,下面代码是创建jdk代理工厂的代码:
public class JDKProxyFactory implements InvocationHandler{
private Object targetObject;
public Object createProxyIntance(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
Object result = null;
//..... advice()-->前置通知
try {
result = method.invoke(targetObject, args);
// afteradvice() -->后置通知
} catch (RuntimeException e) {
//exceptionadvice()--> 例外通知
}finally{
//finallyadvice(); -->最终通知
}
return result;
}
}
剖析:Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(), this.targetObject.getClass().getInterfaces(), this)就是用来创建目标对象的代理对象的。
第一个参数表示:要代理的目标对象的类加载器;第二个对象表示:目标对象的所有接口;第三个参数类型是InvocationHandler,凡是后面带Handler的都表示回调:所以第三
个参数表示的是一个回调。这个回调需要继承InvocationHandler接口,这个接口有个public Object invoke(Object proxy, Method method, Object[] args)方法,没当代理对象调
用目标对象的方法的时候,就会促发该方法。
另需注意:JDK实现的动态代理有一个局限性,就是目标对象必须实现了接口。如果不实现接口就不能用。
二、CGlib动态代理
cglib动态代理不存在局限性,不要求目标对象必须实现一个接口,下面是一个创建cglib动态工厂的类:
public class CGlibProxyFactory implements MethodInterceptor{
private Object targetObject;
public Object createProxyIntance(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());//非final
enhancer.setCallback(this);
return enhancer.create();
}
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
Object result = methodProxy.invoke(targetObject, args);
return result;
}
}
剖析:从上面代码可以看出来,我们先实例化了一个Enhancer对象,然后把目标对象设为该对象的父类, 然后就该对象就会继承目标对象的所有非final方法,然后也设置
了一个回调,这个回调的地方和JDK的非常相似。
cglib的原理也就是把目标对象设置成为父类。并继承了目标对象的所有方法。