前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Spring 基于 AspectJ 的 AOP 开发

Spring 基于 AspectJ 的 AOP 开发

作者头像
希希里之海
发布于 2019-06-24 01:57:12
发布于 2019-06-24 01:57:12
83300
代码可运行
举报
文章被收录于专栏:weixuqin 的专栏weixuqin 的专栏
运行总次数:0
代码可运行

Spring 基于 AspectJ 的 AOP 开发

在 Spring 的 aop 代理方式中, AspectJ 才是主流。


1. AspectJ 简介

  • AspectJ 是一个基于 java 语言的 AOP 框架
  • Spring 2.0 后新增了对 AspectJ 切点表达式支持
  • @AspectJ 是 AspectJ1.5 新增功能,通过 JDK5注解技术,允许直接在 Bean 类中定义切面
  • 新版本Spring 框架,建议使用 AspectJ 方式来开发 AOP
  • 使用 AspectJ 需要导入 Spring AOP 和 AspectJ 相关 jar 包
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring-aop-4.2.4.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-4.2.4.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

2. 注解开发:环境准备

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->

</beans>

3. @Aspect 提供不同的通知类型

  • @Before 前置通知,相当于 BeforeAdvice
  • @AfterReturning 后置通知,相当于 AfterReturning
  • @Around 环绕通知,相当于 MethodInterceptor
  • @After Throwing 异常抛出通知,相当于 ThrowAdvice
  • After 最终通知,不管是否异常,改通知都会执行
  • DeclareParents 引介通知,相当于 IntroductionInterceptor (不要求掌握)
a. @Before 前置通知

可以在方法中传入 JoinPoint 对象,用来获得切点信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 要增强的代码
@Before(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置通知=========" + joinPoint);
    }
b. @AfterReturning 后置通知

通过 returning 属性,可以定义方法返回值,作为参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// result 拿到返回值
@AfterReturning(value = "execution(* com.test.aspectJ.demo1.ProductDao.update(..))", returning = "result")
public void afterReturning(Object result) {
    System.out.println("后置通知=========="+result);
}
c. @Around 环绕通知
  • around 方法的返回值就是目标代理方法执行返回值
  • 参数为 ProceedingJoinPoint 可以调用拦截目标方法执行
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Around(value = "execution(* com.test.aspectJ.demo1.ProductDao.delete(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    System.out.println("环绕前通知============");
    Object obj = joinPoint.proceed(); //执行目标方法
    System.out.println("环绕后通知==========");
    return obj;
}

重点:如果不调用 ProceedingJoinPoint 的 proceed 方法,那么目标方法就被拦截了。

d. @AfterThrowing 异常抛出通知

通过设置 throwing 属性,可以设置发生异常对象参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.find(..))", throwing = "e")
public void afterThrowing(Throwable e) {
    System.out.println("异常抛出通知==========="+e.getMessage());
}
e. After 最终通知

无论是否出现异常,最终通知总是会被执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.findAll(..))", throwing = "e")
public void afterThrowing(Throwable e) {
    System.out.println("异常抛出通知==========="+e.getMessage());
}

4. 在通知中通过 value 属性定义切点

通过 execution 函数,可以定义切点的方式切入

语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

例如:

  • 匹配所有类 public 方法: execution(public * * (..))
  • 匹配指定包下所有类方法: execution(* com.test.dao.*(.)) //不包含子包 execuiton(* com.test.dao..*(..)) // ..* 表示包,子孙包下所有类
  • 匹配指定类所有方法: execution(* com.atest.service.UserService.*(..))
  • 匹配实现特定接口所有类方法: execution(* com.test.doa.GenericDao + .*(..))
  • 匹配所有 save 开头的方法: execution(* save*(..))

5. 为目标类定义切面类

定义切面类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Aspect
public class MyAspectAnno {}

6. 通过 @Pointcut 为切点命名

  • 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用 @Point 进行定义
  • 切点方法:private void 无参数方法,方法名为切点名
  • 当通知多个切点时,可以使用 || 进行连接
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Pointcut(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
private void myPointcut1() {}

具体代码:SpringDemo1.demo1()


基于 AsepctJ 的 XML 方法的 AOP 开发

1. 编写切面类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyAspectXml {

    //前置通知
    public void before(JoinPoint joinPoint) {
        System.out.println("XML方法的前置通知=========="+joinPoint);
    }

    // 后置通知
    public void afterReturning(Object result) {
        System.out.println("XML方法的后置通知==========="+result);
    }

    //环绕通知
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("XML方式的环绕前通知==========");
        Object obj = joinPoint.proceed();
        System.out.println("XML方式的环绕后通知");
        return obj;
    }

    // 异常抛出通知
    public void afterThrowing(Throwable e) {
        System.out.println("XML方法的异常抛出通知"+e.getMessage());
    }

    // 最终通知
    public void after() {
        System.out.println("XML方法的最终通知");
    }

}

2. 完成切面类的配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.test.aspectJ.demo2.MyAspectXml" />

3. 配置 AOP 完成增强

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- aop 的相关配置 -->
<aop:config>
    <!-- 配置切入点 -->
    <aop:pointcut id="pointcut1" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.save())" />
    <aop:pointcut id="pointcut2" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.update())" />
    <aop:pointcut id="pointcut3" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.delete())" />
    <aop:pointcut id="pointcut4" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findOne())" />
    <aop:pointcut id="pointcut5" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findAll())" />
    <!-- 配置AOP的切面 -->
    <aop:aspect ref="myAspectXml">
        <!-- 配置前置通知 -->
        <aop:before method="before" pointcut-ref="pointcut1" />
        <!-- 配置后置通知 -->
        <aop:after-returning method="afterReturning" pointcut-ref="pointcut2" returning="result" />
        <!-- 配置环绕通知 -->
        <aop:around method="around" pointcut-ref="pointcut3" />
        <!-- 配置异常抛出通知 -->
        <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
        <!-- 配置最终通知 -->
        <aop:after method="after" pointcut-ref="pointcut5" />
    </aop:aspect>
</aop:config>

具体代码:SpringDemo2.demo1()

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-06-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
AOP开发明确的的事项
Spring 框架监控切入点方法的执行。一旦监控到切入点方法被运行,使用代理机制,动态创建目标对象的代理对象,根据通知类别,在代理对象的对应位置,将通知对应的功能织入,完成完整的代码逻辑运行。
楠羽
2023/10/17
1860
AOP开发明确的的事项
Spring AOP简介及相关案例
会洗碗的CV工程师
2023/10/14
2110
Spring AOP简介及相关案例
spring中的AOP
切入点(Pointcut): 用于指定哪些组件哪方法使用切面组件,Spring提供表达式来实现该制定。
HUC思梦
2020/09/03
3290
SSH框架之Spring第三篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
海仔
2019/09/23
3390
Spring框架(六)SpringAOP的介绍,Aspectj方式实现,注解方式
实现功能的扩展,可以在springAop下有一个这个方式进行实现。这个就是Aspectj.
一写代码就开心
2021/07/08
3880
【SSM_03】Spring-AOP
一、AOP概述 1. 什么是AOP * AOP是面向切面编程,在不修改代码的情况下,增强功能。 2. AOP的底层实现 * JDK :通过接口实现 * CGlib :通过子类实现 # Spring 会根据目标类是否实现了接口来决定使用那种动态代理方式 3. AOP的相关概念 * Target(目标对象):需要增强的对象 * Proxy(代理对象):被增强后的代理对象 * JoinPoint(接入点):有被增强资格的对象 * PointCut(切点):被增强的对象 * Advice(通知):增强的逻辑对象
用户8250147
2021/02/04
2520
10 Spring框架 AOP (三) Spring对AspectJ的整合
上两节我们讲了Spring对AOP的实现,但是在我们的开发中我们不太使用Spring自身的对AOP的实现,而是使用AspectJ,AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件,如果我们要单独的使用Aspect,我们需要安装,并配置环境变量,但是Spring对AspectJ做了很好的整合,我们只需要将相关的jar包导入,就可以在Spring的环境下使用AspectJ。 本节主要讲解Spring
MindMrWang
2018/04/16
9480
10 Spring框架 AOP (三) Spring对AspectJ的整合
[Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言:  在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习. 一, AspectJ的概述: AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。 Spring为了简化自身的AOP的开发,将AspectJ拿过来作为Spring自身一个AOP的开发. 二,
一枝花算不算浪漫
2018/05/18
6490
Spring AOP 详解
出处:http://www.cnblogs.com/frankliiu-java/archive/2010/01/05/1639664.html
全栈程序员站长
2021/05/19
3890
_Spring AOP简介及相关案例
OK,确实是打印了发送邮件,因此该多切面配置成功,下面接着讲解用另外几种方法实现AOP ,让我们一起学习啪
会洗碗的CV工程师
2023/11/19
1520
_Spring AOP简介及相关案例
SpringAOP
动态代理分两种 JDK动态代理:只能对实现了接口的类产生代理 Cglib动态代理:第三方代理技术,对没有实现接口的类产生代理对象,生成子类对象,可以动态添加类的属性和方法
用户3112896
2019/09/26
2930
Spring 详解(二)------- AOP关键概念以及两种实现方式
当我们为系统做参数验证,登录权限验证或者日志操作等,为了实现代码复用,我们可能把日志处理抽离成一个新的方法。但是这样我们仍然必须手动插入这些方法,这样的话模块之间高耦合,不利于后期的维护和功能的扩展,有了 AOP 我们可以将功能抽成一个切面,代码复用好,低耦合。
海向
2019/09/23
6490
Spring 详解(二)------- AOP关键概念以及两种实现方式
Spring AOP:面向切面编程的利器
总之,Spring AOP是一种非常强大的编程技术,它可以帮助我们实现代码的解耦和复用,提高代码的可维护性和可扩展性。
小小程序员
2023/03/19
3850
Spring AOP:面向切面编程的利器
Spring-AOP之aspectj注解方式
一、简介 1、AOP用在哪些方面:AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制,异常处理等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。 2、AOP中的概念: Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象. joinpoint(连接点):所谓连接点是指那些被拦截到的点(可以是方法、属性、或者类的初始化时机(可以是A
java达人
2018/01/31
1.3K0
spring aop实例讲解_Spring Framework
关于切入点表达式,大家需要好好练习才能深入理解其中含义。即使看的懂,但是写起来却非常麻烦,并没有想象中那么简单。
全栈程序员站长
2022/09/22
3000
Spring AOP使用
AOP全程是Aspect—Oriented—Programming,面向切面编程。AOP采用横向抽取机制,将分散在各个方法中的重复代码抽取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。
ha_lydms
2023/08/09
1730
Spring AOP使用
spring的AOP
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
逍遥壮士
2020/09/18
4490
spring的AOP
Spring高手之路19——Spring AOP注解指南
在现代软件开发中,面向切面编程(AOP)是一种强大的编程范式,允许开发者跨越应用程序的多个部分定义横切关注点(如日志记录、事务管理等)。本文将介绍如何在Spring框架中通过AspectJ注解以及对应的XML配置来实现AOP,在不改变主业务逻辑的情况下增强应用程序的功能。
砖业洋__
2024/06/16
4950
Spring高手之路19——Spring AOP注解指南
Spring-AOP思想
加入Jar包 com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aop-4.3.18.RELEASE.jar spring-aspects-4.3.18.RELEASE.jar
Java开发者之家
2021/06/17
2690
Spring 框架学习(六)面向切面编程 AOP
在软件开发中散布于应用中多处的功能被称为横切关注点(crossing-cutting concern)。通常这也横切关注点一般是与业务逻辑相分离的。而面向切面编程将会解决如何将横切关注点与与业务逻辑分离的问题。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nRIEcgxi-1571404087194)(en-resource://database/9500:1)] 横切关注点往往是影响应用多处的功能
求和小熊猫
2020/11/25
3520
相关推荐
AOP开发明确的的事项
更多 >
LV.5
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验