当前位置 : 主页 > 编程语言 > java >

《Java 核心技术 卷1》 笔记 第六章 接口和内部类(7) 动态代理

来源:互联网 收集:自由互联 发布时间:2022-07-13
6.5.2 动态代理 Java常用的动态代理有两种:JDK动态代理和cglib动态代理 下载地址参考: maven下载地址: ​​https://mvnrepository.com/artifact/cglib/cglib-nodep/2.2​​ 若资源失效,可考虑百度网盘


6.5.2 动态代理

Java常用的动态代理有两种:JDK动态代理和cglib动态代理

下载地址参考:

maven下载地址:

​​https://mvnrepository.com/artifact/cglib/cglib-nodep/2.2​​

若资源失效,可考虑百度网盘下载:

​​百度网盘cglib资源​​

提取码:fhgq

JDK动态代理

  • 是java.lang.reflect 包中内容,无需额外导入包
  • 实现InvocationHandler
  • 固定写法,invoke 调用原类中方法
  • 可在调用前后加入额外处理内容
  • 创建代理类对象
  • 创建原类对象
  • 使用getProxy() 获取代理内容
  • 使用代理调用方法,查看效果
  • public class TestProxy {
    public static void main(String[] args) {
    //5. 创建代理类对象
    JDKProxy jdkProxy = new JDKProxy();
    //6. 创建原类对象
    JDKService jdkService = new JDKServiceImpl();
    //7. 使用getProxy()获取代理内容
    JDKService proxyJdkSerice = (JDKService) jdkProxy.getProxy(jdkService);
    //8. 使用代理调用方法,查看效果
    System.out.println(proxyJdkSerice.query());
    proxyJdkSerice.insert();

    }//1. 是java.lang.reflect,包中内容,无需额外导入包
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    //2. 实现InvocationHandler
    public class JDKProxy implements InvocationHandler {

    //3. 固定写法,invoke调用原类中方法
    public JDKProxy(){}

    private Object target;
    public Object getProxy(Object obj){
    this.target = obj;
    return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),target.getClass().getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("使用JDK代理调用方法-"+method.getName()+"-start");
    //4. 可在调用前后加入额外处理内容
    Object ans = method.invoke(target,args);
    System.out.println("使用JDK代理调用方法-"+method.getName()+"-end");
    return ans;
    }
    }public interface JDKService {
    String query();
    void insert();
    }public class JDKServiceImpl implements JDKService {
    @Override
    public String query() {
    return "query";
    }

    @Override
    public void insert() {
    System.out.println("insert");
    }
    }

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(7) 动态代理_核心技术

    CGLIB代理

  • 非原生内容,需要导入包
  • 《Java 核心技术 卷1》 笔记 第六章 接口和内部类(7) 动态代理_开发语言_02

  • 实现 MethodInterceptor
  • 添加过滤器
  • 过滤器返回1,不用经过代理类(相当于直接调用方法)
  • 返回0经过代理类
  • 经过代理可走前置后置代理类处理方法
  • 后续创建代理对象、源对象,getProxy获取代理,调用方法和jdk代理基本相同
  • public class TestProxy {
    public static void main(String[] args) {
    //7.后续创建代理对象、源对象,getProxy获取代理,调用方法和jdk代理相同
    CglibProxy cglibProxy = new CglibProxy();
    CglibService cglibService = new CglibService();
    cglibProxy.getProxy(cglibService);
    CglibService cglibServiceProxy = (CglibService) cglibProxy.getProxy(cglibService);
    System.out.println(cglibServiceProxy.query());
    cglibServiceProxy.insert();
    }
    }public class CglibProxy implements MethodInterceptor {
    private static CglibFilter filter = new CglibFilter();
    private Enhancer enhancer = new Enhancer();
    public Object getProxy(Object obj){
    enhancer.setSuperclass(obj.getClass());
    enhancer.setCallbacks(new Callback[]{this, NoOp.INSTANCE});
    //3. 添加过滤器
    enhancer.setCallbackFilter(filter);
    return enhancer.create();
    }
    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    //6. 经过代理可走前置后置代理类处理方法
    System.out.println("before do something");//前置代码
    Object res = methodProxy.invokeSuper(object,args);
    System.out.println("after do something");//后置代码
    return res;
    }
    }public class CglibFilter implements CallbackFilter {
    private Set<String> whiteList = new HashSet<>(Arrays.asList("query"));
    @Override
    public int accept(Method method) {
    //4. 过滤器返回1,不用经过代理类(相当于直接调用方法)
    if(inWhiteList(method.getName()))
    return 1;
    //5. 返回0经过代理类
    return 0;
    }

    private boolean inWhiteList(String methodName){
    if(whiteList.contains(methodName))
    return true;
    return false;
    }
    }

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(7) 动态代理_java_03

    jdk代理和cglib动态代理的选用:

  • 实现接口用jdk代理,没实现接口用cglib动态代理
  • 代理处理内容较少,可以用jdk代理,不用额外导入包。它是基于反射机制,当处理内容较多,调用次数较频繁情况下,处理速度会相对慢
  • 代理处理内容较多,可以用cglib代理,它是基于字节码处理的,实际运行处理速度上更快
  •  系列内容:

    《Java 核心技术 卷1》 笔记:第一章 Java程序设计概述

    《Java 核心技术 卷1》 笔记:第二章 Java程序设计环境

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(1)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(2)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(3)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(4)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(5)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(6)

    《Java 核心技术 卷1》 笔记:第三章 Java基本的程序设计结构(7)大数处理、数组、多维数组、控制台传参

    《Java 核心技术 卷1》 笔记 第四章:类与对象

    《Java 核心技术 卷1》 笔记 第四章:类与对象(2) GregorianCalendar 与 类的基本组成

    《Java 核心技术 卷1》 笔记 第四章:类与对象(3) 构造器全局私有方法

    《Java 核心技术 卷1》 笔记 第四章:类与对象(4) 静态字段+静态方法+工厂方法

    《Java 核心技术 卷1》 笔记 第四章:类与对象(5) 形参与实参 构造器的默认值与默认构造

    《Java 核心技术 卷1》 笔记 第四章:类与对象(6) 构造器调用与初始化块

    《Java 核心技术 卷1》 笔记 第四章:类与对象(7) 注释、JavaDoc与类设计

    《Java 核心技术 卷1》 笔记 第五章 继承

    《Java 核心技术 卷1》 笔记 第五章 继承(2)

    《Java 核心技术 卷1》 笔记 第五章 继承(3)

    《Java 核心技术 卷1》 笔记 第五章 继承(4)equals方法

    《Java 核心技术 卷1》 笔记 第五章 继承(5)hashCode 与 toString

    《Java 核心技术 卷1》 笔记 第五章 继承(6) 泛型

    《Java 核心技术 卷1》 笔记 第五章 继承(7) 包装类和可变数组

    《Java 核心技术 卷1》 笔记 第五章 继承(8) 枚举类与类反射

    《Java 核心技术 卷1》 笔记 第五章 继承(9) 异常捕获与反射运用

    《Java 核心技术 卷1》 笔记 第五章 继承(10)反射

    《Java 核心技术 卷1》 笔记 第五章 继承(11)反射泛型数组+方法指针+类设计技巧

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(2)

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(3) 接口回调与内部类

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(4) 局部内部类和局部内部类引用方法变量分析

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(5) 匿名内部类和静态内部类

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(6) 静态代理

    喜欢的话,点个赞吧~!平时做题,以及笔记内容将更新到公众号。

    关注公众号,互相学习:钰娘娘知识汇总

    《Java 核心技术 卷1》 笔记 第六章 接口和内部类(7) 动态代理_java_04

    网友评论