spring核心技术(下)--面向切面aop的特点加案例论证

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: spring核心技术(下)--面向切面aop的特点加案例论证

一.spring的aop的特点

      Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架 。 上一篇已经讲解了IoC控制反转的特点,今天我们来了解面向切面AOP的世界吧!!


       1.1 aop的简介

               Spring的AOP(面向切面编程)可以理解为在编程中,我们常常会有一些通用的功能需求,比如记录日志、事务管理、权限验证等一些非业务核心代码。这些功能可能会散落在很多代码中,如果每次都手动去添加这些功能,不仅麻烦还容易出错。而AOP就是为了解决这个问题而产生的。

      1. AOP的第一个特点是它能够将这些通用功能从业务逻辑中分离出来,形成一个独立的模块,我们把这个模块称为切面(Aspect)。切面里面包含了要执行的通用功能代码。
       2. 松耦合:AOP通过在运行时动态地将切面织入到目标对象中,实现了对目标对象的横向切面扩展。这种方式不需要修改目标对象的代码,只需要在配置文件中指定切点和切面的关系,从而实现了目标对象和切面之间的松耦合。
       3. 代码复用:AOP将通用功能封装在切面中,可以在多个目标对象中复用同一个切面,避免了代码的重复编写,提高了代码的复用性。
       4. 面向切面的编程:AOP允许我们通过切面来对多个目标对象的多个方法进行统一的管理。我们可以在切面中定义通用的功能,并通过切点来指定目标对象的哪些方法需要应用这个通用功能。

       总的来说,AOP的特点包括将通用功能从业务逻辑中分离出来、松耦合、代码复用和面向切面的编程。这些特点使得AOP成为了一个重要的编程范式,可以提高代码的可维护性、可扩展性和开发效率。

       1.2 举例

               比如:当我们大家伙合伙做一个线上书城的项目,如果其中有个贪心的人使用系统,上架了一本明令禁止售卖的书,然后被人举报了,但是这个时候贪心的人下架了该书,而那个人又没有截图,证据,那是不是就发现不了,再者如果客户已经在该系统中下单,但是,客户付了钱之后,那个贪心的人想白嫖将该订单删除,那是不是就没有记录,客户也找不到投诉,那么这个时候,我们就要在系统添加日志文件,记录每一次的交易,上架,下架的数据,那么是不是就可以被记录,而spring的aop就是这样的来完成这些,除必要的增删改之外的技术代码,非业务的核心代码

二.spring的aop的专业术语

       之前我们的项目代码但是从上往下依次执行,而现在加入了面向切面的思想,所以当我们的代码执行到目标对象是,查看连接点是否有前置通知,先执行前置通知,再执行目标方法,如果没有前置通知,那么就直接执行目标方法,最后看连接点上是否有后置通知,如果有,就再执行后置通知,如果没有就执行完了

  1. 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.
  2. 目标(Target):被通知(被代理)的对象,就是完成具体的业务逻辑 ,比如书籍的增删改查
  3. 通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)  ,完成切面编程,非业务核心代码
  4. 代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),  例子:外科医生+护士只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的
  5. 切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点 , (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序),比如给新增方法添加日志功能
  6.  适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

        注:目标对象只负责业务逻辑代码

       通知对象负责AOP代码,这二个对象都没有AOP的功能,只有代理对象才有

三.论证模拟

       3.1.前置通知

      首先,我们先写service接口和实现类进行模拟,在里面写两个方法

package com.zking.aop.service;
/**
 * @author yinzi
 * @create 2023-08-17 14:52
 */
public interface IBookService {
    // 购书
    public boolean buy(String userName, String bookName, Double price);
    // 发表书评
    public void comment(String userName, String comments);
}

       然后,写实现类,重新这两个方法,并且做了一个价格的判断

package com.zking.aop.service;
import com.zking.exception.PriceException;
/**
 * @author yinzi
 * @create 2023-08-17 14:54
 */
public class BookServiceImpl implements IBookService{
    public BookServiceImpl() {
        super();
    }
    public boolean buy(String userName, String bookName, Double price) {
        // 通过控制台的输出方式模拟购书
        if (null == price || price <= 0) {
            throw new PriceException("book price exception");
        }
        System.out.println(userName + " 买了 " + bookName + ", 花了 " + price);
        return true;
    }
    public void comment(String userName, String comments) {
        // 通过控制台的输出方式模拟发表书评
        System.out.println(userName + "评论:" + comments);
    }
}

      接下来要写上面价格判断的异常

package com.zking.exception;
public class PriceException extends RuntimeException {
  public PriceException() {
    super();
  }
  public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
  }
  public PriceException(String message, Throwable cause) {
    super(message, cause);
  }
  public PriceException(String message) {
    super(message);
  }
  public PriceException(Throwable cause) {
    super(cause);
  }
}

      然后,我们先创建一个类,将类名.方法名,携带的参数,作为日志存储到数据库。

package com.zking.aop.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
/**
 * 调用项目中的某一接口实现类的方式时,将类名.方法名,携带的参数,作为日志存储到数据库。
 * @author yinzi
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        String targetName = target.getClass().getName();//方法类
        String methodName = method.getName();//方法的名字
        String params = Arrays.toString(args);//方法参数
        String msg = "【系统日志】:前置日志->"+targetName+"."+methodName+",携带的参数:"+params;
        System.out.println(msg);
    }
}

       最后,我们进行一个配置

前台论证:

       3.2.后置通知

      有了前面的铺垫,现在我们直接再创建一个后置通知的类,比起前置通知,多了一个参数,就是返回参数

package com.zking.aop.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
 * @author yinzi
 * @create 2023-08-17 15:51
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        String targetName = target.getClass().getName();
        String methodName = method.getName();
        String params = Arrays.toString(args);
        String msg = "【系统日志】:后置日志->" + targetName + "." + methodName + ",携带的参数:" + params + ";目标对象所调用的方法的返回值:"
                + returnValue;
        System.out.println(msg);
    }
}

      其次,配置文件即可

最后,前台看结果:

       3.3.环绕通知

       就是结合了前置通知和后置通知,它两个都有所以一般常用这个,

      它只有一个参数,但是这一个参数相当于上面前置通知和后置通知的3,4个参数

package com.zking.aop.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
 * 环绕通知
 * @author Administrator
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object target = invocation.getThis();
        Method method = invocation.getMethod();
        Object[] args = invocation.getArguments();
        String targetName = target.getClass().getName();
        String methodName = method.getName();
        String params = Arrays.toString(args);
        String msg = "【环绕通知】:正在调用->" + targetName + "." + methodName + ",携带的参数:" + params;
        System.out.println(msg);
        Object returnValue = invocation.proceed();
        String msg2 = "【环绕通知】:目标对象所调用的方法的返回值:" + returnValue;
        System.out.println(msg2);
        return returnValue;
    }
}

           然后就是配置文件

最后前台测试:

   3.4.异常通知

       老样子,先建一个类,但是注意,这个异常通知的类,重写的话,方法名字只能是这个,否则报错

然后就是配置文件

最后前台测试;

因为前面那个异常的类,及service类做了价格的判断

       3.5.过滤通知

       过滤通知就是那个适配器,它不需要再建一个类,直接再配置文件里面配置就可以了,需要正则判断,这里举例过滤的是后置通知

前台结果:

今天就分享到这啦!!

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
2月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
384 0
|
2月前
|
SQL Java 数据库连接
Spring Data JPA 技术深度解析与应用指南
本文档全面介绍 Spring Data JPA 的核心概念、技术原理和实际应用。作为 Spring 生态系统中数据访问层的关键组件,Spring Data JPA 极大简化了 Java 持久层开发。本文将深入探讨其架构设计、核心接口、查询派生机制、事务管理以及与 Spring 框架的集成方式,并通过实际示例展示如何高效地使用这一技术。本文档约1500字,适合有一定 Spring 和 JPA 基础的开发者阅读。
291 0
|
1月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
2月前
|
监控 安全 Java
Spring Cloud 微服务治理技术详解与实践指南
本文档全面介绍 Spring Cloud 微服务治理框架的核心组件、架构设计和实践应用。作为 Spring 生态系统中构建分布式系统的标准工具箱,Spring Cloud 提供了一套完整的微服务解决方案,涵盖服务发现、配置管理、负载均衡、熔断器等关键功能。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
192 1
|
2月前
|
监控 Kubernetes Cloud Native
Spring Batch 批处理框架技术详解与实践指南
本文档全面介绍 Spring Batch 批处理框架的核心架构、关键组件和实际应用场景。作为 Spring 生态系统中专门处理大规模数据批处理的框架,Spring Batch 为企业级批处理作业提供了可靠的解决方案。本文将深入探讨其作业流程、组件模型、错误处理机制、性能优化策略以及与现代云原生环境的集成方式,帮助开发者构建高效、稳定的批处理系统。
333 1
|
2月前
|
Java 数据库连接 开发者
Spring Framework 核心技术详解
本文档旨在深入解析 Java Spring Framework 的核心技术原理与应用。与侧重于快速开发的 Spring Boot 不同,本文将聚焦于 Spring 框架本身的设计理念、核心容器、控制反转(IoC)、面向切面编程(AOP)、数据访问与事务管理等基础且强大的模块。通过理解这些核心概念,开发者能够更深刻地领悟 Spring 生态系统的设计哲学,并具备解决复杂企业级应用开发问题的能力。
203 4
|
3月前
|
Java 应用服务中间件 开发者
Spring Boot 技术详解与应用实践
本文档旨在全面介绍 Spring Boot 这一广泛应用于现代企业级应用开发的框架。内容将涵盖 Spring Boot 的核心概念、核心特性、项目自动生成与结构解析、基础功能实现(如 RESTful API、数据访问)、配置管理以及最终的构建与部署。通过本文档,读者将能够理解 Spring Boot 如何简化 Spring 应用的初始搭建和开发过程,并掌握其基本使用方法。
326 2
|
3月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
2月前
|
监控 Java API
Spring WebFlux 响应式编程技术详解与实践指南
本文档全面介绍 Spring WebFlux 响应式编程框架的核心概念、架构设计和实际应用。作为 Spring 5 引入的革命性特性,WebFlux 提供了完全的响应式、非阻塞的 Web 开发栈,能够显著提升系统的并发处理能力和资源利用率。本文将深入探讨 Reactor 编程模型、响应式流规范、WebFlux 核心组件以及在实际项目中的最佳实践,帮助开发者构建高性能的响应式应用系统。
475 0
|
2月前
|
监控 Cloud Native Java
Spring Integration 企业集成模式技术详解与实践指南
本文档全面介绍 Spring Integration 框架的核心概念、架构设计和实际应用。作为 Spring 生态系统中的企业集成解决方案,Spring Integration 基于著名的 Enterprise Integration Patterns(EIP)提供了轻量级的消息驱动架构。本文将深入探讨其消息通道、端点、过滤器、转换器等核心组件,以及如何构建可靠的企业集成解决方案。
228 0