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日

相关文章

  • 使用Lua编写Nginx服务器的认证模块的方法

    下面是详细讲解如何使用Lua编写Nginx服务器的认证模块。 1. 什么是Nginx Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器。常用于静态文件的服务和监视HTTP流量的代理服务器,同时具有负载均衡、容错、安全性高等特点。 2. 认证模块简介 Nginx服务器提供了一种叫做“模块”的技术,可以通过编写自定…

    人工智能概览 2023年5月25日
    00
  • 分享MySQL的自动化安装部署的方法

    分享MySQL的自动化安装部署的方法 在MySQL的自动化安装部署过程中,可以使用Ansible等自动化工具。本文主要介绍使用Ansible进行MySQL自动化安装部署的方法。 步骤1:安装Ansible 首先需要在控制机上安装Ansible,可以通过以下命令进行安装: yum install epel-release -y yum install ansi…

    人工智能概览 2023年5月25日
    00
  • nginx日志导入elasticsearch的方法示例

    以下是详细的攻略: 1. 确认环境和安装 Elasticsearch 和 Logstash 在开始前,需要确认服务器已经安装好 Elasticsearch 和 Logstash。如果还没有安装,需要先进行安装,可以参考 Elasticsearch 和 Logstash 官方文档进行安装。 2. 配置 Logstash 处理 nginx 日志 2.1 创建 L…

    人工智能概览 2023年5月25日
    00
  • 详解Python用户登录接口的方法

    详解Python用户登录接口的方法 本篇攻略介绍了在Python中实现用户登录接口的方法,具体包括以下步骤: 创建一个HTTP POST请求,包含用户提交的登录数据,比如用户名和密码 在后端服务器中对这些数据进行验证 如果验证通过,创建一个session来保持用户的登录状态 返回登录结果到前端 HTTP POST请求 在Python中,我们可以使用reque…

    人工智能概览 2023年5月25日
    00
  • java程序员自己的图片转文字OCR识图工具分享

    我可以为您提供Java程序员自己的图片转文字OCR识图工具分享的完整攻略。下面是具体的步骤: Step 1:安装Tesseract OCR引擎 Tesseract OCR是Google开源的OCR引擎,可以进行文字识别,Java程序员可以将其封装成Java调用库。在开始这个工具的开发之前,我们需要先安装Tesseract OCR引擎。具体的安装步骤可以参考T…

    人工智能概览 2023年5月25日
    00
  • python如何在pygame中设置字体并显示中文详解

    Python是游戏开发者、学生以及任何对编写个性化软件和网站有兴趣的人认为最先进的编程语言之一。而pygame则是Python的游戏开发框架之一,可以让程序员使用Python编写2D游戏。 在使用pygame设计游戏时,可能需要显示中文字体了,那么接下来我将详细解释如何设置中文字体并在pygame中显示它们。 步骤一:准备中文字体文件 我们需要一个支持中文的…

    人工智能概览 2023年5月25日
    00
  • Django Form and ModelForm的区别与使用

    Django是一款常用的Web开发框架,它提供了丰富的功能和组件来帮助开发者创建高效的Web应用程序。其中,Form和ModelForm是Django中非常重要的两个组件,用于处理表单数据和数据模型。本文将深入探讨Django Form和ModelForm的区别和使用。 1. Form和ModelForm的区别 在Django中,Form和ModelForm…

    人工智能概论 2023年5月25日
    00
  • OpenCV HSV颜色识别及HSV基本颜色分量范围

    标题:OpenCV HSV颜色识别及HSV基本颜色分量范围 介绍 OpenCV是一个强大的计算机视觉库,可以用于图像处理、模式识别、机器人视觉等领域,其中HSV颜色空间被广泛应用于颜色检测和跟踪。HSV颜色空间由三个分量组成:色调(Hue)、饱和度(Saturation)和亮度(Value),通过调整颜色分量的范围可以实现各种不同的颜色识别。本文将简单介绍O…

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