https://www.cnblogs.com/rinack/p/7742682.html
JDK动态代理是基于接口的方式,换句话来说就是代理类和目标类都实现同一个接口,那么代理类和目标类的方法名就一样了,CGLib动态代理是代理类去继承目标类,然后重写其中目标类的方法啊,这样也可以保证代理类拥有目标类的同名方法
aop底层实现:基于JDK的动态代理 和 基于Cglib的动态代理
aop的重点概念:
Pointcut(切入点):被增强的方法
Advice(通知/ 增强):封装增强业务逻辑的方法
Aspect(切面):切点+通知
Weaving(织入):将切点与通知结合的过程
jdk动态代理
public interface TargetInterface {
public void method();
}
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
Target target = new Target(); //创建目标对象
//创建代理对象
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
.getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("前置增强代码...");
Object invoke = method.invoke(target, args);
System.out.println("后置增强代码...");
return invoke;
}
}
);
// 测试,当调用接口的任何方法时,代理对象的代码都无需修改
proxy.method();
cglib 的动态代理
cglib 创建某个类A的动态代理类的模式是:
- 查找A上的所有非final的public类型的方法定义;
- 将这些方法的定义转换成字节码;
- 将组成的字节码转换成相应的代理的class对象;
- 实现MethodInterceptor接口,用来处理对代理类上所有方法的请求(这个接口和JDK动态代理InvocationHandler的功能和角色是一样的)
package samples;
/**
* 程序猿类
* @author louluan
*/
public class Programmer {
public void code()
{
System.out.println("I'm a Programmer,Just Coding.....");
}
}
package samples;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/*
* 实现了方法拦截器接口
*/
public class Hacker implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("**** I am a hacker,Let's see what the poor programmer is doing Now...");
proxy.invokeSuper(obj, args);
System.out.println("**** Oh,what a poor programmer.....");
return null;
}
}
package samples;
import net.sf.cglib.proxy.Enhancer;
public class Test {
public static void main(String[] args) {
Programmer progammer = new Programmer();
Hacker hacker = new Hacker();
//cglib 中加强器,用来创建动态代理
Enhancer enhancer = new Enhancer();
//设置要创建动态代理的类
enhancer.setSuperclass(progammer.getClass());
// 设置回调,这里相当于是对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实行intercept()方法进行拦截
enhancer.setCallback(hacker);
Programmer proxy =(Programmer)enhancer.create();
proxy.code();
}
}
package samples;
import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class Programmer
EnhancerByCGLIB
fa7aa2cd extends Programmer
implements Factory
{
//......省略
private MethodInterceptor CGLIB$CALLBACK_0; // Enchaner传入的methodInterceptor
// ....省略
public final void code()
{
MethodInterceptor tmp4_1 = this.CGLIB$CALLBACK_0;
if (tmp4_1 == null)
{
tmp4_1;
CGLIB$BIND_CALLBACKS(this);//若callback 不为空,则调用methodInterceptor 的intercept()方法
}
if (this.CGLIB$CALLBACK_0 != null)
return;
//如果没有设置callback回调函数,则默认执行父类的方法
super.code();
}
//....后续省略
}
网友评论