Spring-Spring之AOP底层原理解析---实践(动态代理)

news2024/11/22 11:10:43

动态代理

代理模式的解释:其他对象提供一种代理以控制对这个对象的访问,增强一个类中的某个方法,对程序进行扩展。

cglib动态代理 方式一:

public class UserService  {
 
 public void test() {
  System.out.println("test...");
 }
 
}
UserService target = new UserService();
 
// 通过cglib技术
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(UserService.class);
 
// 定义额外逻辑,也就是代理逻辑
enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
 @Override
 public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
  System.out.println("before...");
  Object result = methodProxy.invoke(target, objects);
  System.out.println("after...");
  return result;
 }
}});
 
// 动态代理所创建出来的UserService对象
UserService userService = (UserService) enhancer.create();
 
// 执行这个userService的test方法时,就会额外会执行一些其他逻辑
userService.test();

执行结果:

cglib动态代理 方式二

声明两个不同的方法

public class UserService  {
 
 public void test() {
  System.out.println("test...");
 }

public void a() {
  System.out.println("aaaaa...");
 }

 
}

添加无任何逻辑的拦截器:NoOp.INSTANCE

然后执行不同的代理方法test() 和a()

public static void main(String[] args) {

        UserService target = new UserService();

        // 通过cglib技术
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(UserService.class);

        // 定义额外逻辑,也就是代理逻辑
        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("before...");
//                Object result = methodProxy.invoke(target, objects);
//                Object result = methodProxy.invokeSuper(o, objects);
                Object result = method.invoke(target, objects);
                System.out.println("after...");
                return result;
            }
        }, NoOp.INSTANCE}); //NoOp.INSTANCE为无任何逻辑的拦截器

        enhancer.setCallbackFilter(new CallbackFilter() {
            @Override
            public int accept(Method method) {
                if(method.getName().equals("test")){
                    return 0; //该数字为上面数组拦截器的下标
                }else {
                    return 1;
                }
            }
        });

        // 动态代理所创建出来的UserService对象
        UserService userService = (UserService) enhancer.create();

        // 执行这个userService的test方法时,就会额外会执行一些其他逻辑
        userService.test();
        //userService.a();
    }

当代理执行  userService.test();时,结果:

当代理执行  userService.a();时,结果:

JDK动态代理:

基于接口的动态代理

public interface UserInterface {
 public void test();
}
 
public class UserService implements UserInterface {
 
 public void test() {
  System.out.println("test...");
 }
 
}
   public static void main(String[] args) {
        UserService target = new UserService();

        // UserInterface接口的代理对象
        Object proxy = Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("before...");
                Object result = method.invoke(target, args);
                System.out.println("after...");
                return result;
            }
        });

        UserInterface userService = (UserInterface) proxy;
        userService.test();



    }

执行结果:

Spring中的动态代理:

ProxyFactory

public class UserService  {
 
 public void test() {
  System.out.println("test...中奖了");
 }

public void a() {
  System.out.println("aaaaa...");
 }

 
}
public static void main(String[] args) {  
    UserService target = new UserService();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(target);
        proxyFactory.setInterfaces(UserInterface.class);
        proxyFactory.addAdvice(new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                System.out.println("before...买彩票");
                Object result = invocation.proceed();
                System.out.println("after...兑换成功");
                return result;
            }
        });

        UserInterface userService = (UserInterface) proxyFactory.getProxy();
        userService.test();




    }

执行结果:

 Advice的分类

Before Advice:方法之前执行
After returning advice:方法return后执行
After throwing advice:方法抛异常后执行
After (finally) advice:方法执行完finally之后执行,这是最后的,比return更后
Around advice:这是功能最强大的Advice,可以自定义执行顺序

public class UserService  {
 
 public void test() {
  System.out.println("test...中奖了");
 }

public void a() {
  System.out.println("aaaaa...");
 }

 
}

 Before Advice:方法之前执行
After returning advice:方法return后执行

After (finally) advice:方法执行完finally之后执行,这是最后的,比return更后
Around advice:这是功能最强大的Advice,可以自定义执行顺序

public class ZsjBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("中奖之前,先去买财票");
    }
}
public class ZsjAfterAdvice implements AfterReturningAdvice {


    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("中奖后去兑换财票,换钱");
    }
}
public static void main(String[] args) {  
    UserService target = new UserService();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(target);
        proxyFactory.setInterfaces(UserInterface.class);
      
        proxyFactory.addAdvice(new ZsjBeforeAdvice());
        proxyFactory.addAdvice(new ZsjAfterAdvice());


        UserInterface userService = (UserInterface) proxyFactory.getProxy();
        userService.test();




    }

执行结果:

After throwing advice:方法抛异常后执行

public static void main(String[] args) {  
    UserService target = new UserService();

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(target);
        proxyFactory.setInterfaces(UserInterface.class);
      
        proxyFactory.addAdvice(new ZsjBeforeAdvice());
        proxyFactory.addAdvice(new ZsjAfterAdvice());
      proxyFactory.addAdvice(new ZsjThrowAdvice());

        UserInterface userService = (UserInterface) proxyFactory.getProxy();
         userService.a();




    }
public class ZsjThrowAdvice implements ThrowsAdvice {

    public void afterThrowing(Method method, Object[] objects, Object target,NullPointerException e){
        System.out.println("方法抛出异常后执行");
    }

}

执行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

k8s自定义Endpoint实现内部pod访问外部应用

自定义endpoint实现内部pod访问外部应用 endpoint除了可以暴露pod的IP和端口还可以代理到外部的ip和端口 使用场景 公司业务还还没有完成上云, 一部分云原生的,一部分是实体的 业务上云期间逐步实现上云,保证各个模块之间的解耦性 比如使…

IEEE--DSConv: Efficient Convolution Operator 论文翻译

论文地址:https://arxiv.org/pdf/1901.01928v1.pdf 目录 摘要 1 介绍 2 相关工作 3 DSConv层 4 量化过程 5 分布偏移 6 优化推断 7 训练 8 结果 8.1 ImageNet 8.2 内存和计算负载 8.3 转移性 9 结论 摘要 我们引入了一种卷积层的变体,称为DSConv&…

网络编程 —— TCP 和 UDP 编程详解

目录 网络编程主要函数介绍 1. socket 函数 2. bind 函数 3. listen 函数 4. accept 函数 5. connect 函数 6. send 函数 7. recv 函数 8. recvfrom 函数 9. sendto 函数 TCP 和 UDP 原理上的区别 TCP 编程 服务端代码: 客户端代码: UDP 编…

如何进行iOS技术博客的备案?

​ 如何进行iOS技术博客的备案? 标题:iOS技术博客备案流程及要求解析 摘要: 在本篇问答中,我们将为iOS技术博主介绍如何进行备案。如果你的iOS应用只包含简单的页面,并通过蓝牙进行数据采集和传输,那么你…

0基础学习VR全景平台篇第121篇:认识视频剪辑软件Premiere

上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 大家好,这节课是带领大家认识认识我们的剪辑软件Premiere,一般简称是PR。 (PR界面) 我们首先打开PR,第一步就是要创建…

LeetCode【238】除自身意外的数组的乘积

题目&#xff1a; 思路&#xff1a; https://zhuanlan.zhihu.com/p/109306706?utm_id0 代码&#xff1a; int n nums.length;int[] l new int[nums.length];int[] r new int[nums.length];l[0] 1;r[n-1] 1;for (int i1;i<nums.length;i) {l[i] l[i-1] * nums[i-1]…

python数据处理作业4:使用numpy数组对象,随机创建4*4的矩阵,并提取其对角元素

每日小语 真理诚然是一个崇高的字眼&#xff0c;然而更是一桩崇高的业绩。如果人的心灵与情感依然健康&#xff0c;则其心潮必将为之激荡不已。——黑格尔 难点&#xff1a;如何创建&#xff1f;取对角元素的函数是什么&#xff1f; gpt代码学习 import numpy as np# 随机创…

基于springboot实现体育场馆运营平台项目【项目源码】计算机毕业设计

基于springboot实现体育场馆运营平台演示 系统开发平台 在该数码论坛系统中&#xff0c;Eclipse能给用户提供更多的方便&#xff0c;其特点一是方便学习&#xff0c;方便快捷&#xff1b;二是有非常大的信息储存量&#xff0c;主要功能是用在对数据库中查询和编程。其功能有比…

Databend 与海外某电信签约:共创海外电信数据仓库新纪元

为什么选择 Databend 海外某电信面临的主要挑战是随着业务量的增加&#xff0c;传统的 Clickhouse Hive 方案在数据存储和处理上开始显露不足。 原来的大数据分析采用的 Clickhouse Hive 方案进行离线的实时报表。但随着业务量的上升后&#xff0c;Hive的数据存储压力变大&…

微服务基础,分布式核心,常见微服务矿建,SpringCloud概述,搭建SpringCloud微服务项目详细步骤,含源代码

微服务基础 系统架构的演变 随着会联网的发展&#xff0c;网站应用的规模不断扩大&#xff0c;常规的应用架构已经无法应对&#xff0c;分布式服务架构以及微服务架构势在必行&#xff0c;必须一个治理系统确保架构有条不紊的演进 单体应用框架 Web应用程序发展的早期&…

Jenkins中强制停止停不下来的job

# Script console 执行脚本 Jenkins 的提供了 script console 的功能&#xff0c;允许你写一些脚本&#xff0c;来调度 Jenkins 执行一些任务。 我们就可以利用 script console 来强制停止 job 执行。 首先进入 Jenkins 的 script console 页面&#xff1a; script console 路…

8.指令格式,指令的寻址方式

目录 一. 指令格式 二. 扩展操作码 三. 指令寻址 &#xff08;1&#xff09;指令寻址 &#xff08;2&#xff09;数据寻址 1.直接寻址 2.间接寻址 3.寄存器寻址 4.寄存器间接寻址 5.隐含寻址 6.立即寻址 7.基址寻址 8.变址寻址 9.相对寻址 10.堆栈寻址 一. 指令…

HTML 之常用标签的介绍

文章目录 h标签p标签a标签img 标签table、tr、td标签ul、ol、li 标签div 标签 h标签 <h> 标签用于定义 HTML 文档中的标题&#xff0c;其中 h 后面跟着一个数字&#xff0c;表示标题的级别。HTML 提供了 <h1> 到 <h6> 六个不同级别的标题&#xff0c;其中 &…

bclinux aarch64 ceph 14.2.10 对象存储 http网关 CEPH OBJECT GATEWAY Civetweb

相关内容 bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds&#xff1a; ceph-deploy mds-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【3】vdbench fsd 文件系统测试-CSDN博客 ceph-deploy bclinux aarch64 ceph 14.2.10【2】vdbench rbd 块设…

桥接模式 rust和java的实现

文章目录 桥接模式介绍应用实例优点缺点使用场景关键角色 实现javarsut rust代码仓库 桥接模式 桥接&#xff08;Bridge&#xff09;是用于把抽象化与实现化解耦&#xff0c;使得二者可以独立变化。这种类型的设计模式属于结构型模式&#xff0c;它通过提供抽象化和实现化之间…

JS操作canvas

<canvas>元素本身并不可见&#xff0c;它只是创建了一个绘图表面并向客户端js暴露了强大的绘图API。 1 <canvas> 与图形 为优化图片质量&#xff0c;不要在HTML中使用width和height属性设置画布的屏幕大小。而要使用CSS的样式属性width和height来设置画布在屏幕…

STM32中独立看门狗和窗口看门狗的使用方法

独立看门狗&#xff08;Independent Watchdog&#xff0c;IWDG&#xff09;和窗口看门狗&#xff08;Window Watchdog&#xff0c;WWDG&#xff09;是STM32微控制器中提供的两种看门狗定时器。看门狗定时器是一种硬件计时器&#xff0c;用于监视系统的运行状态&#xff0c;并在…

HTTP/2.0协议详解

前言 HTTP/2.0&#xff1a;互联网通信的革新标准 随着互联网技术的飞速发展&#xff0c;HTTP协议作为互联网应用最广泛的通信协议&#xff0c;也在不断演进和优化。HTTP/2.0是HTTP协议的最新版本&#xff0c;它旨在提供更高效、更安全、更快速的互联网连接。 一、HTTP/2.0的…

​软考-高级-系统架构设计师教程(清华第2版)【第6章 数据库设计基础知识(234~262)-思维导图】​

软考-高级-系统架构设计师教程&#xff08;清华第2版&#xff09;【第6章 数据库设计基础知识&#xff08;234~262&#xff09;-思维导图】 课本里章节里所有蓝色字体的思维导图

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测

多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测 目录 多维时序 | MATLAB实现PSO-LSTM-Attention粒子群优化长短期记忆神经网络融合注意力机制的多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果…