**
CGlib动态代理:
**
使用前提:导入cglib-nodep-3.3.0.jar包,里面有asm.jar包,下载链接link
CGlib动态代理原理:
动态生成一个委托类的子类,子类重写代理类的所有不是final的方法,在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势植入横切逻辑。它比使用java反射的JDK动态代理要快。(利用ASM开源宝,对代理对象类的class文件加载进来,通过修改其字节码文件生成子类来处理)
CGlib动态代理底层:
使用字节码处理框架ASM,来转换字节码并生成新的类,不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。
CGlib动态代理优缺点:
优点:可以代理没有实现的接口,可以代理普通类
缺点:委托类被final修饰,那么它不可被继承·,即不可被代理。如果委托类中存在final修饰的方法,那么该方法也不可以被代理。
CGlib动态代理 例子:
TaretClass.class
public interface TargetClass {
public<T> T run(String j,String a);
public void fly();
}
TargetClassImp.class
public class TargetClassImp implements TargetClass{
@Override
public String run(String j,String k) {
System.out.println("跑");
return j+k;
}
@Override
public void fly() {
System.out.println("飞");
}
}
User.class
public class UserClass {
public void thinking(){
System.out.println("思考");
}
}
TargetPorxy.class
//代理类的一部分
public class TargetProxy implements MethodInterceptor {
public<T> T getProxy(Class clazz){
// 利用CGLIB.jar组件生成动态代理对象
Enhancer enhancer=new Enhancer();
// 设置父类
enhancer.setSuperclass(clazz);
// 设置会回调
enhancer.setCallback(this);
return (T)enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println(method.getName()+"方法前");
/* 情况1:接口已有实现类 调用目标方法
return methodProxy.invokeSuper(o,objects);*/
// 情况2:接口没有实现类
StringBuffer s = new StringBuffer();
for (int i = 0; i <objects.length ; i++) {
if(objects[i] instanceof String){
String object=(String)objects[i];
s.append(object);
}
}
s.append("执行完了");
/* 情况3:代理一个普通的类
Object result=methodProxy.invokeSuper(o,objects);
System.out.println(method.getName()+"方法后");*/
return s;
}
}
底层实现的真正代理类(情况2生成的)
public class TargetClass$$EnhancerByCGLIB$$5e7f7ce8 implements TargetClass, Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$equals$0$Method;
private static final MethodProxy CGLIB$equals$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$toString$1$Method;
private static final MethodProxy CGLIB$toString$1$Proxy;
private static