jdk动态代理与cglib代理区别1

发布时间:2024年01月04日

动态代理有jdk动态代理及cglib代理,下面描述jdk动态代理

jdk动态代理

看了 上云 老师的视频,得出此理解

pom文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
</dependencies>

目标类? IStudentServiceImpl

//目标执行接口
public interface IStudentService {

    void save();

    List<Student> query();
}


//目标执行类实现
@Service
public class IStudentServiceImpl implements IStudentService {

    private static final Logger logger= LoggerFactory.getLogger(IStudentServiceImpl.class);

    @Override
    public void save() {
        logger.info("新增功能...");
    }

    @Override
    public List<Student> query() {
        logger.info("查询功能...");
        return new ArrayList<>();
    }
}

增强类?TransactionService


@Service
public class TransactionService{

    private static final Logger logger= LoggerFactory.getLogger(TransactionService.class);

    public void before(){
        logger.info("开始事务...");
    }

    public void after(){
        logger.info("结束事务...");
    }

}

代理类


public class TransactionHandler implements InvocationHandler {

    private Object obj; //目标对象

    private TransactionService transactionService; //增强方法

    public TransactionHandler(Object obj, TransactionService transactionService) {
        this.obj = obj;
        this.transactionService = transactionService;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        if ("save".equals(method.getName())) {
            transactionService.before();
            result = method.invoke(obj,args);
            transactionService.after();
        } else {
            result = method.invoke(obj,args);
        }
        return result;
    }
}

Junit测试类


public class TestStudent {

    @Test
    public void test(){
        //增强类
        TransactionService transactionService=new TransactionService();
        //目标类对象
        IStudentService studentService=new IStudentServiceImpl();
        //方法拦截处理器
        TransactionHandler transactionHandler = new TransactionHandler(studentService, transactionService);
        //获取代理实例对象
        IStudentService proxyInstance = (IStudentService)Proxy.newProxyInstance(IStudentServiceImpl.class.getClassLoader(), IStudentServiceImpl.class.getInterfaces(), transactionHandler);
        proxyInstance.save();
        saveProxyClass("D:\\programs\\idea\\projects\\demo1\\src\\");
    }

    private void saveProxyClass(String path){
        byte[] proxy1s = ProxyGenerator.generateProxyClass("$Proxy1", IStudentServiceImpl.class.getInterfaces());
        FileOutputStream out=null;
        try {
            out=new FileOutputStream(new File(path+"$Proxy1.class"));
            out.write(proxy1s);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(out!=null){
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

结论

可以看到:在src目录下生成一个class类[$Proxy1.class],此文件可以看到 该代理子类通过调用InvocationHandler的invoke方法实现了目标类的方法。

$Proxy1.class文件内容如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import com.example.demo.service.IStudentService;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.List;

public final class $Proxy1 extends Proxy implements IStudentService {
    private static Method m1;
    private static Method m3;
    private static Method m4;
    private static Method m2;
    private static Method m0;

    public $Proxy1(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 void save() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final List query() throws  {
        try {
            return (List)super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    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 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"));
            m3 = Class.forName("com.example.demo.service.IStudentService").getMethod("save");
            m4 = Class.forName("com.example.demo.service.IStudentService").getMethod("query");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

由此可得出结论:底层实现了个Proxy的子类,Proxy里面有需要实现的增强方法,通过反射机制生成一个子类实现InvocationHandler接口,实现动态代理。
通过代理类对象调用方法时,会先调用其重写的invoke方法,里面再调用原方法。

文章来源:https://blog.csdn.net/qq_37342720/article/details/135392247
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。