Spring5深入浅出篇:基于注解实现的AOP

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
函数计算FC,每月15万CU 3个月
简介: # Spring5 AOP 深入理解:注解实现本文介绍了基于注解的AOP编程步骤,包括原始对象、额外功能、切点和组装切面。步骤1-3旨在构建切面,与传统AOP相似。示例代码展示了如何使用`@Around`定义切面和执行逻辑。配置中,通过`@Aspect`和`@Around`注解定义切点,并在Spring配置中启用AOP自动代理。进一步讨论了切点复用,避免重复代码以提高代码维护性。通过`@Pointcut`定义通用切点表达式,然后在多个通知中引用。此外,解释了AOP底层实现的两种动态代理方式:JDK动态代理和Cglib字节码增强,默认使用JDK,可通过配置切换到Cglib

Spring5深入浅出篇:基于注解实现的AOP

基于注解的AOP编程的开发步骤

  1. 原始对象
  2. 额外功能
  3. 切⼊点
  4. 组装切⾯

可以发现其实1,2,3最终目的就是为了去组装切面,其实这里和我们传统开发aop的步骤是一样的

# 通过切⾯类 定义了 额外功能 @Around
 定义了 切⼊点 @Around("execution(* login(..))")
 @Aspect 切⾯类
 
package com.baizhiedu.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/*
传统使用配置文件开发aop步骤
 1. 额外功能
 public class MyArround implements MethodInterceptor{
 public Object invoke(MethodInvocation invocation){
     Object ret = invocation.proceed();
     return ret;
  }
 }
 2. 切⼊点
 <aop:config
 <aop:pointcut id="" expression="execution(*login(..))"/>
 */
@Aspect
public class MyAspect {
 //这里通过注解的方式定义切入点表达式
 @Around("execution(* login(..))")
 public Object arround(ProceedingJoinPoint joinPoint) throws
Throwable {
  //增强额外方法,这里还是通过日志的形式表现
 System.out.println("----aspect log ------");
 //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
 Object ret = joinPoint.proceed();
 return ret;
 }
}
<bean id="userService"
class="com.baizhiedu.aspect.UserServiceImpl"/>
 <!--
 切⾯
 1. 额外功能
 2. 切⼊点
 3. 组装切⾯
 -->
<bean id="arround" class="com.baizhiedu.aspect.MyAspect"/>
<!--告知Spring基于注解进⾏AOP编程-->
<aop:aspectj-autoproxy />

细节

切⼊点复⽤

首先第一个问题,为什么需要切入点复用呢?主要是为了在同一个切入点增加一个额外方法,比如我们给切入点添加了日志方法还需要添加事务相关方法时,就需要重复编码导致代码可维护性差

首先看如下代码

@Aspect
public class MyAspect {
 //这里通过注解的方式定义切入点表达式
 @Around("execution(* login(..))")
 public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
  //增强额外方法,这里还是通过日志的形式表现
  System.out.println("----aspect log ------");
 //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
   Object ret = joinPoint.proceed();
  return ret;
 }
    
    //可以明显发现这里写了重复的代码,如果我们需要将login方法替换成register方法将会需要修改每一个
     @Around("execution(* login(..))")
 public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable {
  //增强额外方法,这里还是通过日志的形式表现
  System.out.println("----事务相关操作 ------");
 //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint
   Object ret = joinPoint.proceed();
  return ret;
 }  
}

通过切入点注解 @Pointcut 进行优化

切⼊点复⽤:在切⾯类中定义⼀个函数 上⾯@Pointcut注解 通过这种⽅式,定义切
⼊点表达式,后续更加有利于切⼊点复⽤。
@Aspect
public class MyAspect {
    
 @Pointcut("execution(* login(..))")
 public void myPointcut(){}
    
 @Around(value="myPointcut()")
 public Object arround(ProceedingJoinPoint joinPoint) throws Throwable {
     System.out.println("----aspect log ------");
     Object ret = joinPoint.proceed();
     return ret;
 }
    
 @Around(value="myPointcut()")
 public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable {
     System.out.println("----aspect tx ------");
     Object ret = joinPoint.proceed();
     return ret;
 }
}

动态代理的创建⽅式

AOP底层实现 2种代理创建⽅式
1. JDK 通过实现接⼝ 做新的实现类⽅式 创建代理对象
2. Cglib通过继承⽗类 做新的⼦类 创建代理对象
默认情况 AOP编程 底层应⽤JDK动态代理创建⽅式
如果切换Cglib
 1. 基于注解AOP开发
 <aop:aspectj-autoproxy proxy-target-class="true" />
 2. 传统的AOP开发
 <aop:config proxy-target-class="true">
 </aop>

AOP阶段知识总结


以上便是本文的全部内容,我是全干程序员demo,每天为你带来最新好用的开发运维工具,如果你觉得用,请点赞,让更多的人了解相关工具

如果你想了解更多关于全干程序员demo,还有更多付费工具免费破解,可以关注公众号-全干程序员demo,后面文章会首先同步至公众号

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
2月前
|
Java 开发者 Spring
【SpringBoot 异步魔法】@Async 注解:揭秘 SpringBoot 中异步方法的终极奥秘!
【8月更文挑战第25天】异步编程对于提升软件应用的性能至关重要,尤其是在高并发环境下。Spring Boot 通过 `@Async` 注解简化了异步方法的实现。本文详细介绍了 `@Async` 的基本用法及配置步骤,并提供了示例代码展示如何在 Spring Boot 项目中创建与管理异步任务,包括自定义线程池、使用 `CompletableFuture` 处理结果及异常情况,帮助开发者更好地理解和运用这一关键特性。
125 1
|
2月前
|
缓存 Java 数据库连接
Spring Boot奇迹时刻:@PostConstruct注解如何成为应用初始化的关键先生?
【8月更文挑战第29天】作为一名Java开发工程师,我一直对Spring Boot的便捷性和灵活性着迷。本文将深入探讨@PostConstruct注解在Spring Boot中的应用场景,展示其在资源加载、数据初始化及第三方库初始化等方面的作用。
53 0
|
6天前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
7天前
|
Java Spring 容器
Spring使用异步注解@Async正确姿势
Spring使用异步注解@Async正确姿势,异步任务,spring boot
|
6天前
|
XML Java 数据格式
spring复习03,注解配置管理bean
Spring框架中使用注解配置管理bean的方法,包括常用注解的标识组件、扫描组件、基于注解的自动装配以及使用注解后的注意事项,并提供了一个基于注解自动装配的完整示例。
spring复习03,注解配置管理bean
|
7天前
|
XML 前端开发 Java
控制spring框架注解介绍
控制spring框架注解介绍
|
20天前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
20天前
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
|
2月前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
23 0
Spring高手之路22——AOP切面类的封装与解析
|
2月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
下一篇
无影云桌面