AOP理解——模拟带有横切逻辑的实例

2023-10-20 04:10

本文主要是介绍AOP理解——模拟带有横切逻辑的实例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Spring使用动态代理技术在运行期间织入增强的代码。Spring AOP 使用两种动态代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理。

带有横切逻辑的实例

package com.hegx.spring.aop.service.impl;

import com.hegx.spring.aop.Forum;
import com.hegx.spring.aop.PerformanceMonitor;
import com.hegx.spring.aop.dao.ForumDao;
import com.hegx.spring.aop.dao.impl.ForumDaoImpl;
import com.hegx.spring.aop.service.ForumService;

/**
 * @Author: hegx
 * @Description:
 * @Date: 14:25 2017/7/16
 */
public class ForumServiceImpl implements ForumService {private ForumDao forumDao = new ForumDaoImpl();

    @Override
    public void remove(Integer forumId) {//开始对方法进行性能监视
        PerformanceMonitor.begin("com.hegx.spring.aop.service.impl.ForumServiceImpl.remove");
        forumDao.remove(forumId);
        try {Thread.currentThread().sleep(20);
        } catch (InterruptedException e) {e.printStackTrace();
        }//结束对方法进行性能监视
        PerformanceMonitor.end();
    }@Override
    public void create(Forum forum) {//开始对方法进行性能监视
        PerformanceMonitor.begin("com.hegx.spring.aop.service.impl.ForumServiceImpl.remove");

        forumDao.create(forum);

        try {Thread.currentThread().sleep(2000);
        } catch (InterruptedException e) {e.printStackTrace();
        }//结束对方法进行性能监视
        PerformanceMonitor.end();
    }
}
 
上面带绿色的代码就是具有横切逻辑的代码,每个dao的实现前后都要执行先后的代码,也就是相同的逻辑。

上面的PerformanceMonitor是性能监视的类,我们给出一个非常简单的实现版本,期待吗如下:

package com.hegx.spring.aop;

/**
 * @Author: hegx
 * @Description:
 * @Date: 14:33 2017/7/16
 */
public class PerformanceMonitor {//通过一个ThreadLocal保存调用线程先关的性能监视信息
    private static  ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<>();

    //启动对某一个方法的性能监视
    public static void begin(String method){System.out.println("begin Monitor...");
        MethodPerformance mp = new MethodPerformance(method);
        performanceRecord.set(mp);
    }//启动对某一个方法的性能监视
    public static void end(){System.out.println("end Monitor...");
        MethodPerformance mp = performanceRecord.get();

        //打印出方法性能监视的结果信息
        mp.printPerformance();
    }}

ThreadLoacl是将非线程安全类改造成线程安全类的法宝。PerformanceMonitor提供两个方法:通过调用begin(String method)方法开始对目标类方法的监视,method是目标类全限定名;而end()方法结束对目标类方法性能监视,并给出性能监视信息。这两个方法必须配套使用。

用于记录性能类的信息MethodPerformance类的代码如下:

package com.hegx.spring.aop;

/**
 * @Author: hegx
 * @Description:用于记录性能监视信息的类
 * @Date: 14:36 2017/7/16
 */
public class MethodPerformance {private Long begin;

    private Long end;

    private String serviceMethod;


    public MethodPerformance(String serviceMethod) {this.serviceMethod = serviceMethod;

        this.begin = System.currentTimeMillis();//记录目标类方法的开始执行点的时间
    }public void printPerformance(){end = System.currentTimeMillis();//获取目标类方法执行完成后的系统时间,并进而计算出目标类方法执行时间

        Long elapse = end - begin;

        System.out.println(serviceMethod+"花费了"+elapse+"毫秒");//打印目标类方法执行的时间
        System.out.println();
    }}

通过下面的代码测试性能监视能力的ForumServiceImpl业务方法:

package com.hegx.spring.aop.test;

import com.hegx.spring.aop.Forum;
import com.hegx.spring.aop.service.ForumService;
import com.hegx.spring.aop.service.impl.ForumServiceImpl;

/**
 * @Author: hegx
 * @Description:测试拥有性能监视能力的TestForumServiceImpl业务方法
 * @Date: 15:10 2017/7/16
 */
public class TestForumService {public static void main(String[] args) {ForumService forumService = new ForumServiceImpl();

        forumService.remove(10);
        forumService.create(new Forum());
    }}

程序执行的结果:



如上图和代码所示,当某个方法在进行性能监视,就必须调整方法的代码,在方法体前后分别添加上开启性能和结束性能监视的代码,这些非业务逻辑的性能监视代码破坏了ForumServiceImpl业务逻辑的纯碎性。我们希望通过代理的方式,将业务类方法中开启和结束性能的这些横切代码从业务类中完全移除。并通过JDK动态代理技术或CGLib动态代理技术奖横切代码动态织入到目标方法的位置。










这篇关于AOP理解——模拟带有横切逻辑的实例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

python运用requests模拟浏览器发送请求过程

《python运用requests模拟浏览器发送请求过程》模拟浏览器请求可选用requests处理静态内容,selenium应对动态页面,playwright支持高级自动化,设置代理和超时参数,根据需... 目录使用requests库模拟浏览器请求使用selenium自动化浏览器操作使用playwright

MySQL多实例管理如何在一台主机上运行多个mysql

《MySQL多实例管理如何在一台主机上运行多个mysql》文章详解了在Linux主机上通过二进制方式安装MySQL多实例的步骤,涵盖端口配置、数据目录准备、初始化与启动流程,以及排错方法,适用于构建读... 目录一、什么是mysql多实例二、二进制方式安装MySQL1.获取二进制代码包2.安装基础依赖3.清

Java Spring的依赖注入理解及@Autowired用法示例详解

《JavaSpring的依赖注入理解及@Autowired用法示例详解》文章介绍了Spring依赖注入(DI)的概念、三种实现方式(构造器、Setter、字段注入),区分了@Autowired(注入... 目录一、什么是依赖注入(DI)?1. 定义2. 举个例子二、依赖注入的几种方式1. 构造器注入(Con

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

Apache Ignite缓存基本操作实例详解

《ApacheIgnite缓存基本操作实例详解》文章介绍了ApacheIgnite中IgniteCache的基本操作,涵盖缓存获取、动态创建、销毁、原子及条件更新、异步执行,强调线程池注意事项,避免... 目录一、获取缓存实例(Getting an Instance of a Cache)示例代码:二、动态

MySQL逻辑删除与唯一索引冲突解决方案

《MySQL逻辑删除与唯一索引冲突解决方案》本文探讨MySQL逻辑删除与唯一索引冲突问题,提出四种解决方案:复合索引+时间戳、修改唯一字段、历史表、业务层校验,推荐方案1和方案3,适用于不同场景,感兴... 目录问题背景问题复现解决方案解决方案1.复合唯一索引 + 时间戳删除字段解决方案2:删除后修改唯一字

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语