Cglib和jdk动态代理的区别?
1、Jdk动态代理:利用拦截器(必须实现InvocationHandler)加上反射机制生成一个代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理
2、Cglib动态代理:利用ASM框架,对代理对象类生成的class文件加载进来,通过修改其字节码生成子类来处理
什么时候用cglib什么时候用jdk动态代理?
1、JDK动态代理只能对实现了接口的类生成代理,而不能针对类
2、Cglib是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法的增强,但是因为采用的是继承,所以该类或方法最好不要生成final,对于final类或方法,是无法继承的
Spring如何选择是用JDK还是cglib?
1、当bean实现接口时,会用JDK代理模式
2、当bean没有实现接口,用cglib实现
3、可以强制使用cglib(在spring配置中加入<aop:aspectj-autoproxy proxyt-target-class=”true”/>)
举例
使用jdk动态代理和cglib动态代理实现Spring AOP。
JDK动态代理
接口
package com.yc.biz;
public interface StudentBiz {
void find(String 张三);
void add(String 李四);
void update(String 王五);
}
目标类
public class StudentBizImpl implements StudentBiz{
@Override
public void find(String name) {
System.out.println("find..........");
}
@Override
public void add(String name) {
System.out.println("add........");
}
@Override
public void update(String name) {
System.out.println("update........");
}
}
InvocationHandler实现类
package com.yc;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
public class LogAspect implements InvocationHandler {
private Object target;
public LogAspect(Object target){
this.target=target;
}
public Object createProxy(){
//新建一个代理实例
///参数????类加载器
return Proxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass().getInterfaces(),this);
}
@Override //回调方法,当java调用代理对象的被代理的方法时,会由jvm自动调用这个invoke
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理类的对象:"+proxy.getClass());
System.out.println("目标类的方法:"+method);
System.out.println("方法中的参数:"+args);
if(method.getName().startsWith("add")){//转换成切入点表达式的解析---》Aspect的切点表达式
//前置增强
log();
}
Object returnValue=method.invoke(this.target,args);
//后置增强
System.out.println("===========after advice============= ");
return returnValue;
}
private void log() {
System.out.println("===========before advice=============");
System.out.println("hello,this is"+new Date());
System.out.println("============before advice结束====");
}
}
测试类
package com.yc;
import com.yc.biz.StudentBiz;
import com.yc.biz.StudentBizImpl;
public class Test {
public static void main(String[] args) {
StudentBiz target= new StudentBizImpl();
LogAspect la=new LogAspect(target);
//创建代理对象
Object obj=la.createProxy(); //obj就是代理对象
System.out.println(obj+"zzzzzzzzzzzzzzz");//相当于调用了obj.toString
if(obj instanceof StudentBiz){
StudentBiz sb=(StudentBiz) obj;
//调用代理对象的被代理方法
sb.find("张三");
sb.add("李四");
sb.update("王五");
}
}
}
代理类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
import com.yc.biz.StudentBiz;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
public final class $Proxy extends Proxy implements StudentBiz {
private static Method m1;
private static Method m2;
private static Method m4;
private static Method m5;
private static Method m3;
private static Method m0;
public $Proxy(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final void update(String var1) throws {
try {
super.h.invoke(this, m4, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void find(String var1) throws {
try {
super.h.invoke(this, m5, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int add(String var1) throws {
try {
return (Integer)super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m4 = Class.forName("com.yc.biz.StudentBiz").getMethod("update", Class.forName("java.lang.String"));
m5 = Class.forName("com.yc.biz.StudentBiz").getMethod("find", Class.forName("java.lang.String"));
m3 = Class.forName("com.yc.biz.StudentBiz").getMethod("add", Class.forName("java.lang.String"));
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
Cglib动态代理
目标类
public class StudentBizImpl {
public int add(String name){
System.out.println("调用了studentBizImpl中的add"+name);
return 100;
}
public void update(String name){
System.out.println("调用了stundetBizImpl中的update"+name);
}
public String find(String name){
System.out.println("调用了studentBizImpl中的find"+name);
return name+"====";
}
}
MethodInterceptor实现类
package com.yc;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Date;
public class LogAspectCglib implements MethodInterceptor {
private Object target;
public LogAspectCglib(Object target) {
this.target = target;
}
public Object createProxy(){
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
if(method.getName().startsWith("add")){
//前置增强
log();
}
Object returnValue=method.invoke(this.target,args);
//后置增强
System.out.println("===========after advice============= ");
return returnValue;
}
private void log() {
System.out.println("===========before advice=============");
System.out.println("hello,this is"+new Date());
System.out.println("============before advice结束====");
}
}
测试类
package com.yc;
import com.yc.biz.StudentBizImpl;
public class Test {
public static void main(String[] args) {
StudentBizImpl target= new StudentBizImpl();
LogAspectCglib la=new LogAspectCglib(target);
//创建代理对象
Object obj=la.createProxy(); //obj就是代理对象
System.out.println(obj+"zzzzzzzzzzzzzzz");//相当于调用了obj.toString
if(obj instanceof StudentBizImpl){
StudentBizImpl sb=(StudentBizImpl) obj;
//调用代理对象的被代理方法
sb.find("张三");
sb.add("李四");
sb.update("王五");
}
}
}