三种代理模式(静态代理,JDK动态代理,cglib动态代理)

66 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

静态代理: 一个新的类,想要代理那个类,那个类里面的方法,然后加自己的逻辑,然后再调用被代理的那个类的方法,因为两个类实现了同一个接口。 实现代理互相嵌套。

动态代理:

JDK动态代理:通过proxy这个类来实现,一个newproxyinstance方法来生成动态代理对象。这个方法的三个参数,第一个是被代理类的类加载器,第二个是被代理对象应该实现的哪个接口(可以实现多个接口),第三个参数,指的是被代理的对象里面的那个方法怎么做处理,比如再这个方法前后做操作。

生成proxy0一个字节码文件,生成一个 proxy0一个字节码文件,生成一个proxy0对象,去调用方法,是调用的生成代理对象的那个方法

接口

public interface StudentDao {
    public abstract void login();
}


实现类

public class StudentDaoImpl implements StudentDao {
    @Override
    public void login() {
        System.out.println("登陆功能");
    }

}

测试

public class Test {
    public static void main(String[] args) {
        StudentDao studentDao = new StudentDaoImpl();
        StudentDao proxyInstance = (StudentDao) Proxy.newProxyInstance(
                studentDao.getClass().getClassLoader(),
				//studentDao.getClass().getInterfaces(),
                //第二种获取接口的方式
                new Class[]{StudentDao.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("权限校验");
                        Object invoke = method.invoke(studentDao, args);
                        System.out.println("日志记录");
                        return invoke;
                    }
                }
        );
        proxyInstance.login();
    }
}

在这里插入图片描述

cglib动态代理:

不需要接口,我们动态生成被代理的类的子类,如果是final就不能生成了 (听说ASM是final还是能改变) JDK代理要求被代理的类必须实现接口,有很强的局限性。而CGLIB动态代理则没有此类强制性要求。简单的说,CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。在CGLIB底层,其实是借助了ASM这个非常强大的Java字节码生成框架。在CGLIB中,方法的调用并不是通过反射来完成的,而是直接对方法进行调用:FastClass对Class对象进行特别的处理,比如将会用数组保存method的引用,每次调用方法的时候都是通过一个index下标来保持对方法的引用

两个动态代理底层都是用的ASM