当前位置: 首页 > news >正文

4. AOP

1 AOP能解决什么问题

1.1 提出问题

1.1.1 情景:数学计算器
1.1.1.1 要求

①执行加减乘除运算
②日志:在程序执行期间追踪正在发生的活动
在这里插入图片描述

ArithmeticCalculator.java

public interface ArithmeticCalculator {double add(double a, double b);double sub(double a, double b);double mul(double a, double b);double div(double a, double b);
}

ArithmeticCalculatorImpl.java

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {@Overridepublic double add(double a, double b) {return a + b;}@Overridepublic double sub(double a, double b) {return a - b;}@Overridepublic double mul(double a, double b) {return a * b;}@Overridepublic double div(double a, double b) {return a / b;}
}
1.1.1.2 常规实现

ArithmeticCalculatorImpl.java

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {@Overridepublic double add(double a, double b) {System.out.println("The method add begins with [" + a + ", " + b + "]");double result = a + b;System.out.println("The method add ends with " + result);return result;}@Overridepublic double sub(double a, double b) {System.out.println("The method sub begins with [" + a + ", " + b + "]");double result = a - b;System.out.println("The method sub ends with " + result);return result;}@Overridepublic double mul(double a, double b) {System.out.println("The method sub begins with [" + a + ", " + b + "]");double result = a * b;System.out.println("The method sub ends with " + result);return result;}@Overridepublic double div(double a, double b) {System.out.println("The method sub begins with [" + a + ", " + b + "]");double result = a / b;System.out.println("The method sub ends with " + result);return result;}
}
1.1.1.3 问题

①代码混乱:越来越多的非业务需求(日志和验证等)加入后,原有的业务方法急剧膨胀。每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点。
②代码分散: 以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块(方法)里多次重复相同的日志代码。如果日志需求发生变化,必须修改所有模块。

1.2 动态代理

1.2.1 动态代理的原理

代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象”取代”原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用转到原始对象上。
在这里插入图片描述

1.2.2 动态代理的方式
  • 基于接口实现动态代理: JDK动态代理
  • 基于继承实现动态代理: Cglib、Javassist动态代理

1.3 数学计算器的改进(JDK动态代理)

1.3.1 日志处理器

CalculatorLoggingHandler.java

public class CalculatorLoggingHandler implements InvocationHandler {private Object target;public CalculatorLoggingHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("The method " + method.getName() + "() begins with " + Arrays.toString(args));Object result = method.invoke(target, args);System.out.println("The method " + method.getName() + "() ends with " + result);return result;}public static Object createProxy(Object target) {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new CalculatorLoggingHandler(target));}
}

1.3.2 测试代码

Main.java

public class Main {public static void main(String[] args) {ArithmeticCalculatorImpl arithmeticCalculator = new ArithmeticCalculatorImpl();ArithmeticCalculator proxy = (ArithmeticCalculator) CalculatorLoggingHandler.createProxy(arithmeticCalculator);System.out.println(proxy.add(12, 13));}
}

1.3.3 测试结果

The method add() begins with [12.0, 13.0]
The method add() ends with 25.0
25.0

相关文章:

  • 单片机MCU堆栈概念与区别
  • 先序+中序还原二叉树【数据结构】
  • Prometheus通过consul实现自动服务发现
  • 搭建在线720虚拟VR展厅,不仅是展厅也是名片
  • 【SpringCloud】从实际业务问题出发去分析Eureka-Server端源码
  • 基于Freeswitch实现的Volte网视频通知应用
  • Git 使用规范:起名字、提交描述的最佳实践
  • Linux(ubuntu)下git / github/gitee使用
  • Java:表单生成excel文档 poi 通用
  • 001、安装 Rust
  • 【软件测试】为bug而生
  • HarmonyOS page生命周期函数讲解
  • 水准网、平面导线平差
  • 双击编辑el-table的单元格数据
  • 【ADB】电脑通过ADB向手机传输文件
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • axios 和 cookie 的那些事
  • Consul Config 使用Git做版本控制的实现
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • django开发-定时任务的使用
  • golang 发送GET和POST示例
  • JS基础篇--通过JS生成由字母与数字组合的随机字符串
  • Python - 闭包Closure
  • Selenium实战教程系列(二)---元素定位
  • sessionStorage和localStorage
  • tweak 支持第三方库
  • vue 个人积累(使用工具,组件)
  • 多线程 start 和 run 方法到底有什么区别?
  • 前端知识点整理(待续)
  • 让你的分享飞起来——极光推出社会化分享组件
  • 如何借助 NoSQL 提高 JPA 应用性能
  • ​Java并发新构件之Exchanger
  • ###C语言程序设计-----C语言学习(6)#
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (二)【Jmeter】专栏实战项目靶场drupal部署
  • (二)fiber的基本认识
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (过滤器)Filter和(监听器)listener
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (六)vue-router+UI组件库
  • (六)什么是Vite——热更新时vite、webpack做了什么
  • (全注解开发)学习Spring-MVC的第三天
  • (十一)手动添加用户和文件的特殊权限
  • (算法)Travel Information Center
  • (五) 一起学 Unix 环境高级编程 (APUE) 之 进程环境
  • (转)Spring4.2.5+Hibernate4.3.11+Struts1.3.8集成方案一
  • (转载)虚函数剖析
  • .[hudsonL@cock.li].mkp勒索病毒数据怎么处理|数据解密恢复
  • .bat批处理(八):各种形式的变量%0、%i、%%i、var、%var%、!var!的含义和区别
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET Framework 服务实现监控可观测性最佳实践
  • .net 发送邮件