Cglib和Jdk动态代理的区别

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("王五");
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值