动态代理(JDK CGLIB)

2024-05-10 11:38
文章标签 动态 jdk 代理 cglib

本文主要是介绍动态代理(JDK CGLIB),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

静态代理,一个代理类只能代理一个接口,好处的简单、好实现、好理解,坏处呢,举个例子,我们知道Mybatis逆向工程会生成N多个Mapper接口文件,如果每个Mapper接口都造一个代理类出来,然后呢,每个代理类做的事情又都是一样的——获取session、解析crud语句、执行crud、处理结果、结束session。

难道我们对此就束手无策了吗?不,使用动态代理,我们可以只造一个轮子就能代理everything。

动态代理分两种:Java动态代理 和 CGLib,其中Java动态代理只能代理实现了接口的类,而CGLib则可以代理一个没有实现任何接口的类

1 JDK动态代理

实现InvocationHandler并重写invoke方法。

public interface Hello {void say(String name);
}
public class HelloImpl implements Hello {@Overridepublic void say(String name) {System.out.println("Hello! " + name);}
}
public class DynamicProxy implements InvocationHandler {//能代理任意一个类private Object target;public DynamicProxy(Object target) {this.target = target;}/*** 能接收任意数量和类型的参数、任意的返回值、任意的异常抛出* @param proxy* @param method* @param args* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {before();Object result = method.invoke(target, args);after();return result;}private void before() {System.out.println("Before");}private void after() {System.out.println("After");}
测试一下:
public class Test {public static void main(String[] args) {Hello hello = new HelloImpl();DynamicProxy dynamicProxyHandler = new DynamicProxy(hello);Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),dynamicProxyHandler);helloProxy.say("biglong");}
}

 

打印出来是:
Before
Hello! biglong
After
——————————————— 割以咏志 ———————————————————————
以上Proxy.newProxyInstance的方法还是有点复杂,需要传入3个参数:

参数1:ClassLoader

参数2:该实现类的所有接口

参数3:动态代理对象

我们可以简化一下:

public class DynamicProxy2 implements InvocationHandler {...@SuppressWarnings("unchecked")public <T> T getProxy() {return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}...
}

测试下:

public class Test2 {public static void main(String[] args) {Hello hello = new HelloImpl();DynamicProxy2 dynamicProxy2 = new DynamicProxy2(hello);Hello helloProxy = dynamicProxy2.getProxy();helloProxy.say("biglong");}
}

输出跟上面一样。

2 CGLib动态代理

如果一个类没有实现任何接口,以上JDK动态代理就成了废物,此时CGLib粉墨登场,CGLib可以代理没有接口的类——我们的Spring框架的AOP就用了这个。

public class CGLibProxy implements MethodInterceptor {//单例模式(懒汉)private static CGLibProxy instance = new CGLibProxy();public static CGLibProxy getInstance() {return instance;}private CGLibProxy() {}@SuppressWarnings("unchecked")public <T> T getProxy(Class<T> cls) {return (T) Enhancer.create(cls, this);}@Overridepublic Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {before();Object result = proxy.invokeSuper(target, args);after();return result;}private void before() {System.out.println("Before");}private void after() {System.out.println("After");}
}

测试一下:

public class Test {public static void main(String[] args) {HelloImpl helloProxy = CGLibProxy.getInstance().getProxy(HelloImpl.class);helloProxy.say("biglong");}
}

 

 

 

这篇关于动态代理(JDK CGLIB)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/976333

相关文章

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

在macOS上安装jenv管理JDK版本的详细步骤

《在macOS上安装jenv管理JDK版本的详细步骤》jEnv是一个命令行工具,正如它的官网所宣称的那样,它是来让你忘记怎么配置JAVA_HOME环境变量的神队友,:本文主要介绍在macOS上安装... 目录前言安装 jenv添加 JDK 版本到 jenv切换 JDK 版本总结前言China编程在开发 Java

go动态限制并发数量的实现示例

《go动态限制并发数量的实现示例》本文主要介绍了Go并发控制方法,通过带缓冲通道和第三方库实现并发数量限制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录带有缓冲大小的通道使用第三方库其他控制并发的方法因为go从语言层面支持并发,所以面试百分百会问到

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可