Aop编程之动态代理

1、Java代理介绍

Java中的代理方式包括静态代理和动态代理。 静态代理在编译期间就确定了代理对象,动态代理是在运行期间动态生成代理对象。动态代理包括cglib动态代理和jdk动态代理,在目标对象有接口的情况下,可以使用jdk动态代理或者cglib动态代理;如果目标对象没有接口,则无法使用jdk动态代理,只能使用cglib动态代理。下面是介绍分别实现cglib动态代理和jdk动态代理的简单例子。

2、cglib动态代理

下面的例子中, 要增强User类的talk()方法,在方法开始和结束时都输出当前的系统时间,但是不希望修改User类的代码,又因为User类没有实现接口,在这种情况下可以使用cglib动态代理实现。

代码逻辑:

  1. 创建User类,并且编写talk()方法;
  2. 创建User类的代理增强类,用于增强talk()方法的代码逻辑;
  3. 编写测试类,先创建一个User对象,然后通过增强类根据这个对象创建一个增强对象,最后执行增强对象的talk方法。

  • User类
public class User {
    public void talk(){
        System.out.println("【交谈中。。。】");
    }
}

  • User代理增强类
  1. 执行Enhancer.create()方法,传入对应的参数,拿到一个增强后的对象;
  2. 重写MethodInterceptor()接口的 intercept()方法 编写具体的增强代码逻辑。
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class UserExtendByCglib {
    public static Object getProxy(Object target){
        /**
         * Enhancer.create()方法, 参数1是对象的字节码, 参数2是拦截方法的程序的对象, 返回值是一个增强后的对象
         */
        return Enhancer.create(target.getClass(), new MethodInterceptor() {
            /**
             * @param proxy  增强后的代理对象
             * @param method  需要代理增强的方法
             * @param args     需要代理增强的方法的参数
             * @param methodProxy  增强后的代理对象的方法
             */
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //增强代码逻辑1:开始时间
                System.out.println(System.currentTimeMillis());
                //执行最初的方法
                Object result = method.invoke(target, args);
                //增强代码逻辑2:结束时间
                System.out.println(System.currentTimeMillis());
                return result;
            }
        });
    }
}

  • 测试代码
public class TestUser {
    public static void main(String[] args) {
        // 创建未被增强的对象
        User user = new User();
        // 通过代理对象, 对初始对象增强, 然后得到一个增强对象
        User userProxy = (User) UserExtendByCglib.getProxy(user);
        // 执行增强后的方法
        userProxy.talk();

    }
}

3、jdk动态代理

在下面的例子中,想要对Student类的talk方法增强,talk是Student实现Talk接口重写后的方法,这种情况可以使用jdk动态代理实现。

代码逻辑:

  1. 定义一个Talk接口,其中包含talk()方法;
  2. 创建Student类,实现Talk接口,重写talk()方法;
  3. 创建Talk接口的代理增强类,用于增强talk()方法的代码逻辑;
  4. 编写测试类,先创建一个Student对象,然后通过增强类根据这个对象创建一个增强对象,最后执行增强对象的talk()方法。
  • 创建talk接口
public interface Talk {
    void talk();
}

  • 创建talk接口的实现类
public class Student implements Talk{
    @Override
    public void talk() {
        System.out.println("【交谈中。。。】");
    }
}

  • 创建talk接口的增强代理类
  1. 通过执行Proxy.newProxyInstance()方法拿到一个代理对象;
  2. 重写接口InvocationHandler的invoke()方法编写具体的增强逻辑。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class TalkProxyByJdk {

    public static Object getProxy(Object target){
        Object proxy = Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {
                    /**
                     * @param proxy  增强后的代理对象
                     * @param method 需要代理增强的方法
                     * @param args   需要代理增强的方法的参数
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开始说话的时间:"+System.currentTimeMillis());
                        Object result = method.invoke(target, args);
                        System.out.println("停止说话的时间:"+System.currentTimeMillis());
                        return result;
                    }
                }
        );
        return proxy;
    }

}

  • 测试代理对象
import java.lang.reflect.Proxy;
public class TestJdkProxy {
   public static void main(String[] args) {
       // 创建初始对象 
        Talk student = new Student();
       // 创建代理对象 
        Talk proxy = (Talk) TalkProxyByJdk2.getProxy(student);
       // 执行代理对象的增强方法 
        proxy.talk();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/308203.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用numpy处理图片——基础操作

大纲 准备工作图片像素大小修改透明度 numpy是一款非常优秀的处理多维数组的Python基础包。在现实中,我们最经常接触的多维数组相关的场景就是图像处理。本系列将通过若干篇对图像处理相关的探讨,来介绍numpy的使用方法,以获得直观的体验。 本…

element-plus里el-date-picker日期选择器,默认值不显示的问题

官网文档给出的示例默认值也是没有没显示的。 找了很多方法&#xff0c;最终是给v-model"defaultTime"绑定初始值&#xff0c;如下代码&#xff0c;需要的可以改一下 <el-date-picker class"top_select" v-model"defaultTime" type"da…

数模学习day11-系统聚类法

本文参考辽宁石油化工大学于晶贤教授的演示文档聚类分析之系统聚类法及其SPSS实现。 目录 1.样品与样品间的距离 2.指标和指标间的“距离” 相关系数 夹角余弦 3.类与类间的距离 &#xff08;1&#xff09;类间距离 &#xff08;2&#xff09;类间距离定义方式 1.最短…

SpringIOC之support模块GenericGroovyApplicationContext

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

职场日常英语口语,成人英语培训学校,柯桥学英语推荐哪里

“玩手机”用英语怎么说&#xff1f;你的第一反应是不是&#xff1a;play the phone&#xff1f; 在英语中&#xff0c;play这个动词通常表示“玩耍、娱乐、操纵”等意思&#xff0c;而手机是一种工具&#xff0c;不是玩耍的对象。 换句话说&#xff0c;我们“玩手机”&#xf…

Web缓存代理

目录 一.Web缓存代理 配置Nginx 缓存代理&#xff1a; 修改web服务器的配置文件&#xff1a; 修改192.168.233.10代理服务器的配置文件&#xff1a; 访问页面看看&#xff1a; 对于一些实时性要求非常高的页面或数据来说&#xff0c;就不应该去设置缓存&#xff0c;下面来…

Confluence跨大版本升级记录

初始版本7.4.18最终升级到了目前的最新版本8.7.1&#xff0c;在升级过程中遇到了很多问题&#xff0c;庆幸的是最后都解决了&#xff0c;记录一下。 背景 初始环境&#xff1a; OS&#xff1a;CentOS8.5 DB&#xff1a;10.8.8-MariaDB Confluence&#xff1a;7.4.18 公司…

c++学习笔记-STL案例-机房预约系统1-需求分析

1 机房预约系统需求 1.1 简单介绍 学校有几个规格不同的机房&#xff0c;由于使用经常出现“撞车”现象&#xff0c;现在开发一套预约系统&#xff0c;解决这一问题。 1.2 身份介绍 分别有三种身份使用该系统 学生代表&#xff1a;申请使用机房教师&#xff1a;审核学生的…

IP地址的网络安全防护和预防

网络安全对于保护个人和组织的信息资产至关重要&#xff0c;而IP地址是网络通信的基础。在这篇文章中&#xff0c;IP数据云将探讨IP地址的网络安全防护和预防措施&#xff0c;以确保网络的安全性和可靠性。 IP地址是互联网上每个设备在网络中的唯一标识符。有IPv4和IPv6两种类…

你Go代码写的像“鸭子”吗???

概 述 Go 语言也提供了接口类型&#xff0c;使得我们可以面向接口编程&#xff0c;将实现和接口分离。在我看来&#xff0c;软件的抽象之美也应该以此来表达&#xff0c;和 Java 语言不同的是 Go 并不是那么 “强制”&#xff0c;它使用了一种 鸭子类型 的方式让动态类型成为可…

75应急响应-数据库漏洞口令检索应急取证箱

必要知识点 第三方应用是选择性的安装的&#xff0c;比如mysql&#xff0c;如何做好信息收集&#xff0c;有没有爆过它的漏洞&#xff0c;和漏洞探针也是获取攻击者思路的重要操作&#xff0c;除去本身漏洞外&#xff0c;提前预知或口令相关攻击也要进行筛选。 排除三方应用…

古典吉他教师阿木:来自新疆的音乐才子

阿木,全名木合汤夏甫依克,于 1990 年 10 月 8 日出生在新疆这片美丽的土地上,是一位哈萨克族人。他是英皇认证古典吉他教师、中国社会艺术吉他考级考官、中国智慧工程研究会艺术教育委员会执行委员、新疆吉他艺术节发起人之一兼评审组组长。 阿木自幼受到哥哥的影响,对吉他产生…

85.乐理基础-记号篇-力度记号

内容来源于&#xff1a;三分钟音乐社 上一个内容&#xff1a;78.乐理基础-非常见拍号如何打拍子-CSDN博客 85-78之间的内容观看索引&#xff1a; 腾讯课堂-三分钟音乐社-打拍子&#xff08;20&#xff09;-总结、重点、练习与检验方法开始看 力度记号&#xff1a;p、f、mp、…

linux和windows机器下创建共享文件夹

1、安装samba sudo apt-get install samba 2、创建共享文件夹 sudo mkdir /smb sudo chmod 777 /smb/ 3、备份配置 sudo cp /etc/samba/smb.conf /etc/samba/smb.conf.bak 4、修改配置 sudo vim /etc/samba/smb.conf 添加以下信息到文件结尾 [SMB share] #描述信息…

Element+vue3.0 tabel合并单元格span-method

Elementvue3.0 tabel合并单元格 span-method :span-method"objectSpanMethod"详解&#xff1a; 在 objectSpanMethod 方法中&#xff0c;rowspan 和 colspan 的值通常用来定义单元格的行跨度和列跨度。 一般来说&#xff0c;rowspan 和 colspan 的值应该是大于等于…

锻炼身体固然好,爱护听力也重要

新年新气象&#xff01;你制定了那些新年计划和目标呢&#xff1f;相信健身一定在不少人的清单里。 根据美国调查网站 FiveThirtyEight 的报告的结果&#xff0c;新年目标的榜单前三是&#xff1a;减肥、健身、成为更好的人。 进入健身房&#xff0c;随着动感的音乐节奏朝着更强…

Map与JSONObject区别

相同点&#xff1a; 都可以存key-value&#xff1b;key是唯一的,如果key重复了会覆盖前面的 不同点&#xff1a; &#xff08;1&#xff09;JSONObject 不可以存空&#xff0c;Map可以存空。 &#xff08;2&#xff09;Map由jdk提供&#xff0c;JsonObject需要第三方jar包提供。…

pc下载apk文件到andriod开发板,并实现可视化

PC端安装APK下载器 点击下载 刷机精灵APK安装器 界面如下&#xff0c;可将下载好的apk文件&#xff0c;直接拖拽到该界面&#xff0c;然后点击安装全部按钮进行安装&#xff0c;安装过程中的具体状态会显示在具体的apk后面。 如下图&#xff0c;安装错误、安装完成等皆为apk安…

如何在IEC61850的ICD文件中添加新的DO节点

写在前面 恭喜“梅山剑客”粉丝突破1K&#xff0c;为了纪念这一伟大的时刻&#xff0c;今日发表此文&#xff0c; 纪念这神圣的时间节点&#xff0c;愿各位 青春永驻&#xff0c;笔耕不息。 本文参考链接&#xff1a; 1、61850开发知识总结与分享 2、IEC61850建模说明 1 简介…

针对大规模服务日志敏感信息的长效治理实践

文章目录 1 背景2 目标与措施3 实施3.1 脱敏工具类3.2 JSON脱敏3.3 APT自动脱敏3.3.1 本地缓存问题3.3.2 JDK序列化问题 3.4 弃用方案 4 规划5 总结 1 背景 近年来&#xff0c;国家采取了多项重要举措来加强个人数据保护&#xff0c;包括实施《中华人民共和国网络安全法》和《…