java动态代理(jdk与cglib)详细解析

Java动态代理(JDK与CGLIB)详细解析

什么是动态代理

代理模式是一种非常常见的设计模式,其核心思想是为其他对象提供一个代理对象来控制对这个对象的访问。静态代理必须手动编写代理类,而动态代理则是在运行期动态生成代理类。

JDK动态代理

JDK动态代理是Java官方提供的动态代理实现方式,它是基于反射机制实现的。JDK动态代理需要实现InvocationHandler接口,具体步骤如下:

  1. 定义委托类和接口

假设有一个接口Shape,和一个具体实现类Circle,我们要实现一个动态代理代理这个实现类。

public interface Shape {
    void draw();
}

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Circle is drawn.");
    }
}
  1. 定义代理类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ShapeProxy implements InvocationHandler {

    private Object target;

    public ShapeProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        System.out.println("Before method " + method.getName() + " is invoked.");
        result = method.invoke(target, args);
        System.out.println("After method " + method.getName() + " is invoked.");
        return result;
    }
}

代理类实现InvocationHandler接口,并持有委托类对象。在invoke方法中,我们可以在委托类方法调用前后做一些额外处理。

  1. 调用
Shape circle1 = new Circle();
Shape circle2 = (Shape) Proxy.newProxyInstance(
    circle1.getClass().getClassLoader(), 
    circle1.getClass().getInterfaces(), 
    new ShapeProxy(circle1));

circle2.draw();

在调用Proxy.newProxyInstance方法时,需要传入委托类的ClassLoader和interface。JVM将根据这些信息动态创建一个代理类的字节码,然后创建实例并返回。

CGLIB动态代理

JDK动态代理只能代理实现了接口的类,如果要代理没有实现接口的类,就需要使用CGLIB动态代理。CGLIB动态代理使用字节码生成技术在运行时动态生成代理类,不需要委托类实现接口。

使用CGLIB需要引入cglib的依赖:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

CGLIB代理步骤如下:

  1. 定义委托类
public class Rectangle {
    public void draw() {
        System.out.println("Rectangle is drawn.");
    }
}
  1. 定义代理类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class RectangleProxy implements MethodInterceptor {

    private Rectangle target;

    public RectangleProxy(Rectangle target) {
        this.target = target;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Object result = null;
        System.out.println("Before method " + method.getName() + " is invoked.");
        result = method.invoke(target, args);
        System.out.println("After method " + method.getName() + " is invoked.");
        return result;
    }

    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Rectangle.class);
        enhancer.setCallback(this);
        return enhancer.create();
    }
}

CGLIB代理类也需要实现一个接口,此处实现的是MethodInterceptor。在intercept方法中,可以对委托类的方法进行增强。

getProxy方法中使用Enhancer.create()方法创建代理类实例。

  1. 调用
Rectangle rectangle1 = new Rectangle();
Rectangle rectangle2 = (Rectangle) new RectangleProxy(rectangle1).getProxy();

rectangle2.draw();

以上就是JDK动态代理和CGLIB动态代理的详细说明,这两种动态代理技术都有各自的特点和使用场景,需要根据实际情况进行选择。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java动态代理(jdk与cglib)详细解析 - Python技术站

(0)
上一篇 2023年5月25日
下一篇 2023年5月25日

相关文章

  • OpenCV实现Sobel边缘检测的示例

    下面是关于“OpenCV实现Sobel边缘检测的示例”的完整攻略。 1. 背景介绍 Sobel算子是图像处理中一种简单有效的边缘检测算法,可用于快速检测图像中的边缘。OpenCV是一个广泛使用的计算机视觉库,可用于各种视觉任务,包括图像处理和图像分析。在这个示例中,我们将学习如何使用OpenCV实现Sobel算子检测图像边缘的方法。 2. 实现步骤 2.1 …

    人工智能概论 2023年5月25日
    00
  • .net Core连接MongoDB数据库的步骤详解

    针对“ .Net Core 连接 MongoDB 数据库的步骤详解”,我将给出以下完整攻略。 1.安装MongoDB 首先需要安装并启动MongoDB数据库。可以从MongoDB官网下载安装程序,安装完成后启动MongoDB。 2.安装MongoDB.Driver 第二步是安装MongoDB.Driver,这是一个.NET的驱动程序包,用于连接MongoDB…

    人工智能概论 2023年5月25日
    00
  • 答题辅助python代码实现

    当我们在做在线测试或考试时,有些题目需要计算或编程才能得出答案,这时使用答题辅助代码可以大大提高答案的准确性和速度。本文将介绍如何使用Python编写答题辅助代码。 步骤一:导入必要的库和数据 首先需要导入Python标准库,例如random库,以产生随机数。此外,用户可根据实际需求导入其他库和数据。 例如,下面的代码段演示了如何使用Python的rando…

    人工智能概论 2023年5月25日
    00
  • 详解Java分布式系统中session一致性问题

    详解Java分布式系统中session一致性问题 什么是session一致性问题 在分布式系统中,由于业务系统的扩展和部署,往往会存在多个应用实例,此时用户的请求可能会被路由到不同的应用实例上,而应用实例之间并不共享服务器内存,因此需要在不同的应用实例之间保证Session数据的一致性,即Session共享。如果没有解决Session共享问题,可能会导致用户…

    人工智能概览 2023年5月25日
    00
  • 浅谈swoole的作用与原理

    浅谈 Swoole 的作用与原理 Swoole 是一款基于 PHP 的协程网络通信引擎,其主要作用是提供异步、高并发的网络通信能力。本文将介绍 Swoole 的作用和原理,并提供两个示例说明。 Swoole 的作用 Swoole 主要用于处理服务器端的网络通信,包括但不限于以下几个方面: 提供异步事件驱动的编程模型,相较于传统的编程模型,更加高效,性能更好;…

    人工智能概览 2023年5月25日
    00
  • Nginx+Tomcat负载均衡集群的实现示例

    下面是“Nginx+Tomcat负载均衡集群的实现示例”的完整攻略。 一、概述 本文将介绍如何使用Nginx和Tomcat搭建负载均衡集群。负载均衡是实现高可用性和高性能关键组件之一,它可以将请求分发到多个服务器上,从而实现负载分担和故障转移。本文将首先介绍负载均衡的原理,然后介绍如何使用Nginx和Tomcat搭建负载均衡集群。 二、负载均衡原理 负载均衡…

    人工智能概览 2023年5月25日
    00
  • C# SDK实现百度云OCR的文字识别功能

    下面是实现C# SDK调用百度云OCR文字识别功能的完整攻略,分为以下几个步骤: 步骤一:注册百度云OCR服务并获取API Key和Secret Key 首先,你需要在百度云AI开放平台上注册一个账号,并创建一个OCR应用。 创建完成之后,你需要从“管理控制台”进入“应用详情”页面,获取你的API Key和Secret Key。 步骤二:安装百度云OCR C…

    人工智能概论 2023年5月25日
    00
  • Python工程师必考的6个经典面试题

    下面我会详细讲解“Python工程师必考的6个经典面试题”的完整攻略。 1. 实现单例模式 单例模式指的是一个类只能创建一个实例。在Python中,实现单例模式有多种方法,包括使用装饰器、使用元类等。以下是使用装饰器的实现代码示例: def singleton(cls): instances = {} def wrapper(*args, **kwargs)…

    人工智能概览 2023年5月25日
    00
合作推广
合作推广
分享本页
返回顶部