首页 > 其他分享 >动态代理

动态代理

时间:2024-01-13 09:05:00浏览次数:19  
标签:连接点 代理 result 日志 动态 方法 method

测试方法 

public class TestAopProxy {
    public static void main(String[] args) {
        ProxyFactory proxyFactory = new ProxyFactory(new CalculatorLogImpl());
        Calculator proxy = (Calculator) proxyFactory.getProxy();
        proxy.add(15 ,5 );
    }
}

目标类

    @Override
    public int sub(int i, int j) {

        System.out.println("[日志] sub 方法开始了,参数是:" + i + "," + j);

        int result = i - j;

        System.out.println("方法内部 result = " + result);

        System.out.println("[日志] sub 方法结束了,结果是:" + result);

        return result;
    }

代理工厂类

public class ProxyFactory {

    private Object target;

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

    public Object getProxy(){

        /**
         * newProxyInstance():创建一个代理实例
         * 其中有三个参数:
         * 1、classLoader:加载动态生成的代理类的类加载器
         * 2、interfaces:目标对象实现的所有接口的class对象所组成的数组
         * 3、invocationHandler:设置代理对象实现目标对象方法的过程,即代理类中如何重写接口中的抽象方法
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /**
                 * proxy:代理对象
                 * method:代理对象需要实现的方法,即其中需要重写的方法
                 * args:method所对应方法的参数
                 */
                Object result = null;
                try {
                    System.out.println("[动态代理][日志] "+method.getName()+",参数:"+ Arrays.toString(args));
                    result = method.invoke(target, args);
                    System.out.println("[动态代理][日志] "+method.getName()+",结果:"+ result);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("[动态代理][日志] "+method.getName()+",异常:"+e.getMessage());
                } finally {
                    System.out.println("[动态代理][日志] "+method.getName()+",方法执行完毕");
                }
                return result;
            }
        };

        return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}

输出结果

[动态代理][日志] add,参数:[15, 5]
[日志] add 方法开始了,参数是:15,5
方法内部 result = 20
[日志] add 方法结束了,结果是:20
[动态代理][日志] add,结果:20
[动态代理][日志] add,方法执行完毕

AOP概念及相关术语

、概述

AOP(Aspect Oriented Programming)是一种设计思想,是软件设计领域中的面向切面编程,它是面向对象编程的一种补充和完善,它以通过预编译方式和运行期动态代理方式实现,在不修改源代码的情况下,给程序动态统一添加额外功能的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

、相关术语

①横切关注点

分散在每个各个模块中解决同一样的问题,如用户验证、日志管理、事务处理、数据缓存都属于横切关注点。

从每个方法中抽取出来的同一类非核心业务。在同一个项目中,我们可以使用多个横切关注点对相关方法进行多个不同方面的增强。

这个概念不是语法层面的,而是根据附加功能的逻辑上的需要:有十个附加功能,就有十个横切关注点。.

 

 

 

 

②通知(增强)

增强,通俗说,就是你想要增强的功能,比如 安全,事务,日志等。

每一个横切关注点上要做的事情都需要写一个方法来实现,这样的方法就叫通知方法。

  • 前置通知:在被代理的目标方法前执行
  • 返回通知:在被代理的目标方法成功结束后执行(寿终正寝)
  • 异常通知:在被代理的目标方法异常结束后执行(死于非命)
  • 后置通知:在被代理的目标方法最终结束后执行(盖棺定论)
  • 环绕通知:使用try…catch…finally结构围绕整个被代理的目标方法,包括上面四种通知对应的所有位置
  •  

③切面

封装通知方法的类。

 

④目标

被代理的目标对象。

⑤代理

向目标对象应用通知之后创建的代理对象。

⑥连接点

这也是一个纯逻辑概念,不是语法定义的。

把方法排成一排,每一个横切位置看成x轴方向,把方法从上到下执行的顺序看成y轴,x轴和y轴的交叉点就是连接点。通俗说,就是spring允许你使用通知的地方

 

⑦切入点

定位连接点的方式。

每个类的方法中都包含多个连接点,所以连接点是类中客观存在的事物(从逻辑上来说)。

如果把连接点看作数据库中的记录,那么切入点就是查询记录的 SQL 语句。

Spring 的 AOP 技术可以通过切入点定位到特定的连接点。通俗说,要实际去增强的方法

切点通过 org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件。

5.3.3、作用

  • 简化代码:把方法中固定位置的重复的代码抽取出来,让被抽取的方法更专注于自己的核心功能,提高内聚性。

  • 代码增强:把特定的功能封装到切面类中,看哪里有需要,就往上套,被套用了切面逻辑的方法就被切面给增强了。

标签:连接点,代理,result,日志,动态,方法,method
From: https://www.cnblogs.com/zhbx/p/17961891

相关文章

  • 【C语言进阶篇】动态内存分配的六个常见错误
    <br>(文章目录)前言  <fontcolor=green>......
  • 使用Nginx作为反向代理服务器在Linux中的最佳实践
    在Linux环境下,Nginx因其高效性能、稳定性以及丰富的功能集而广泛用于作为反向代理服务器。以下是在Linux中使用Nginx作为反向代理服务器的最佳实践:1.安装与配置首先,确保你的Linux发行版已经安装了Nginx。大多数Linux发行版都提供了Nginx的包管理工具。例如,在基于Debian的系统上,你......
  • 安卓仿微信朋友圈动态数据加载(包括评论和点赞,以及动态详情页)
    在项目里面使用到了类似微信朋友圈的功能,所以就研究了一下,大家先看看效果吧!效果图一:效果图二:效果图三:效果图四:效果图五:效果图六:效果图七:效果图八:......
  • 基于物联网的建筑物综合环境能耗监测管理系统是如何对建筑物的能耗进行动态监测的
    1能耗监测管理系统架构设计1.1管理平台系统架构设计建筑综合环境能耗监测管理主要是由感知层,网络层和应用层三层次结构组成。(1)感知层。建筑体内控制设备分散,需要在各个能耗设备终端加入能耗计量采集装置,根据现场情况,采集装置的通信技术可以采用现场总线技术,以太网传输或无线传输方......
  • 鸿蒙原生应用/元服务开发-代理提醒说明(一)
    一、功能介绍应用退到后台或进程终止后,仍然有一些提醒用户的定时类任务,例如购物类应用抢购提醒等,为满足此类功能场景,系统提供了代理提醒(reminderAgentManager)的能力。当应用退至后台或进程终止后,系统会代理应用做相应的提醒。当前支持的提醒类型包括:倒计时、日历和闹钟。倒计时类:基......
  • Spring学习记录之GoF之代理模式
    Spring学习记录之GoF之代理模式前言这篇文章是我第二次学习b站老杜的spring相关课程所进行的学习记录,算是对课程内容及笔记的二次整理,以自己的理解方式进行二次记录,其中理解可能存在错误,欢迎且接受各位大佬们的批评指正;关于本笔记,只是我对于相关知识遗忘时快速查阅了解使用,至......
  • Vue.nextTick在动态更新iframe的src中的使用
    Vue.nextTick在动态更新iframe的src中的使用:https://codeleading.com/article/63673310260/ 当iframe中的地址src需要动态改变时,需要使用Vue.nextTick来切换地址src,否则DOM的地址不会实现更新,而是保持上一次的src。在数据变化后要执行的某个操作,而这个操作需要使用随数据改变......
  • windows使用SSH隧道socks5代理自动运行尝试
    场景在《windows机器SSH隧道访问内网服务》随笔中通过XShell工具,建立SSH隧道提供Sock5代理服务,在使用过程中出现了一些问题,每次都需要手动打开代理,或者因为锁屏或网络问题会频繁断开,每天都要手动操作好多次。很是繁琐,于是想寻求一种自动运行的方式。经过多次尝试,终于使用putty软......
  • Nginx采用虚拟目录的方式代理IIS站点
    Nginx采用虚拟目录的方式代理IIS站点起因背景由于IIS出现了某种不可知的问题,H5APP的部署从IIS改为Nginx。H5APP的Nginx的部署比较简单,直接修改官方的实例即可但是之前H5站点中有一个虚拟目录用于客户单点登录认证,所以需要在Nginx中添加对应的虚拟目录,但是单点认证是ASP.Net......
  • 最新测试,芝麻代理、青果网络、快代理的代理IP哪家好?
    近期,讯代理狗了,想必大家都知道吧?感兴趣的也可以自己看看。历年来,狗了的代理IP服务商不在少数了,从飞蚁、rola、讯代理……这还是做了一定体量,大家略有耳闻的,其他还有更多的小服务商倒下,倒也不是想来说一波创业艰难,我只是心疼打工人的钱和找代理IP的精力。基于行业共识,现在代理IP的头......