Spring 基于AspectJ的AOP

比较Spring AOP和AspectJ 它与我现有的或新的应用程序兼容吗?在哪里可以实施AOP?它与我的应用程序集成的速度有多快?性能开销是多少?在本文中,我们将着眼于回答这些问题,并介绍Spring AOP和AspectJ(这两种最流行的Java AOP框架)。下表概述了Spring AOP和AspectJ之间的主要区别:Spring AOPAspectJImplemented in pure Java-- 用纯Java实现。 阅读详情

Spring基于AspectJ的AOP

execution表达式

execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)

  • 匹配所有类的public方法:execution(public * * (..))
  • 匹配指定包下面所有类的方法(不包含子包):execution(* com.zhangxin9727.*(..))
  • 匹配指定包下面所有类的方法(包含子包):execution(* com.zhangxin9727..*(..))
  • 匹配到指定类所有方法:execution(* com.zhangxin9727.Demo.*(..))
  • 匹配实现特定接口所有类方法:execution(* com.zhangxin9727.Demo+.*(..))
  • 匹配所有demo开头的方法:execution(* demo*(..))

五种常用通知类型

通知类型说明
before前置通知
after-returning后置通知
around环绕通知
after-throwing异常通知
after最终通知

简单案例

目录结构

aspectJDemo
- src
- - main
- - - java
- - - - com.zhangxin9727
- - - - - annotation
- - - - - - AnnotationAspect.java
- - - - - - UserDao1.java
- - - - - xml
- - - - - - UserDao2.java
- - - - - - UserDao2Imp.java
- - - - - - XMLAspect.java
- - - resources
- - - - applicationContext1.xml
- - - - applicationContext2.xml
- - test
- - - java
- - - - MyTest1.java
- - - - MyTest2.java
- pom.xml

主要文件

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <groupId>com.zhangxin9727</groupId>
    <artifactId>aspectJDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.4.0</version>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>
    </dependencies>
</project>
UserDao1.java
package com.zhangxin9727.annotation;

import org.springframework.stereotype.Component;

@Component("userDao1")
public class UserDao1 {
    public void save() {
        System.out.println("增加···");
    }

    public String delete() {
        System.out.println("删除···");
        return "删除成功";
    }

    public void update() {
        System.out.println("修改···");
    }

    public void find() {
        System.out.println("查询单个···");
    }

    public void findAll() {
        System.out.println("查询所有···");
    }
}
AnnotationAspect.java
package com.zhangxin9727.annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AnnotationAspect {
    //定义切点
    @Pointcut(value = "execution(* com.zhangxin9727.annotation.UserDao1.save())")
    private void pointcut() {
    }

    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("===前置通知===" + joinPoint);
    }

    @AfterReturning(value = "execution(* com.zhangxin9727.annotation.UserDao1.delete())", returning = "result")
    public void afterReturning(Object result) {
        System.out.println("===后置通知===" + result);
    }

    @Around(value = "execution(* com.zhangxin9727.annotation.UserDao1.update())")
    public Object around(ProceedingJoinPoint joinPoint) {
        System.out.println("===环绕前通知===");
        Object obj = null;//执行目标方法
        try {
            obj = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("===环绕后通知===");
        return obj;
    }

    @AfterThrowing(value = "execution(* com.zhangxin9727.annotation.UserDao1.find())", throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("===异常抛出通知===" + e.getMessage());
    }

    @After(value = "execution(* com.zhangxin9727.annotation.UserDao1.findAll())")
    public void after() {
        System.out.println("===最终通知===");
    }
}
applocationContext1.xml
<?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"
       xmlns:context="http://www.springframework.org/schema/context"
       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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--开启AspectJ自动代理-->
    <aop:aspectj-autoproxy/>
    <context:component-scan base-package="com.zhangxin9727.annotation"/>
</beans>
MyTest1.java
import com.zhangxin9727.annotation.UserDao1;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import javax.annotation.Resource;

@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:applicationContext1.xml")
public class MyTest1 {
    @Resource(name = "userDao1")
    private UserDao1 userDao;

    @Test
    public void test() {
        userDao.save();
        userDao.delete();
        userDao.update();
        userDao.find();
        userDao.findAll();
    }
}
UserDao2.java
package com.zhangxin9727.xml;

public interface UserDao2 {
    void save();

    String delete();

    void update();

    void find();

    void findAll();
}
UserDao2Imp.java
package com.zhangxin9727.xml;

public class UserDao2Impl implements UserDao2 {
    @Override
    public void save() {
        System.out.println("增加···");
    }

    @Override
    public String delete() {
        System.out.println("删除···");
        return "删除成功";
    }

    @Override
    public void update() {
        System.out.println("修改···");
    }

    @Override
    public void find() {
        System.out.println("查询单个···");
    }

    @Override
    public void findAll() {
        System.out.println("查询所有···");
    }
}
XMLAspect.java
package com.zhangxin9727.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class XMLAspect {
    //前置通知
    public void before(JoinPoint joinPoint) {
        System.out.println("===前置通知===" + joinPoint);
    }

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

    //环绕通知
    public Object around(ProceedingJoinPoint joinPoint) {
        System.out.println("===环绕前通知===");
        Object obj = null;
        try {
            obj = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("===环绕后通知===");
        return obj;
    }

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

    //最终通知
    public void after() {
        System.out.println("最终通知");
    }
}
applicationContext2.xml
<?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 class="com.zhangxin9727.xml.UserDao2Impl" id="userDao2"/>
    <!--配置切面类-->
    <bean class="com.zhangxin9727.xml.XMLAspect" id="xmlAspect"/>
    <!--aop的相关配置-->
    <aop:config>
        <!--配置切入点-->
        <aop:pointcut id="ponitcut" expression="execution(* com.zhangxin9727.xml.UserDao2.save())"/>
        <!--配置AOP的切面-->
        <aop:aspect ref="xmlAspect">
            <aop:before method="before" pointcut-ref="ponitcut"/>
            <aop:after-returning method="afterReturning" pointcut="execution(* com.zhangxin9727.xml.UserDao2.delete())"
                                 returning="result"/>
            <aop:around method="around" pointcut="execution(* com.zhangxin9727.xml.UserDao2.update())"/>
            <aop:after-throwing method="afterThrowing" pointcut="execution(* com.zhangxin9727.xml.UserDao2.find())"
                                throwing="e"/>
            <aop:after method="after" pointcut="execution(* com.zhangxin9727.xml.UserDao2.findAll())"/>
        </aop:aspect>
    </aop:config>
</beans>
MyTest2.java
import com.zhangxin9727.xml.UserDao2;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import javax.annotation.Resource;

@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class MyTest2 {
    @Resource(name = "userDao2")
    private UserDao2 userDao;

    @Test
    public void test() {
        userDao.save();
        userDao.delete();
        userDao.update();
        userDao.find();
        userDao.findAll();
    }
}
学技术学英文:Spring AOP和 AspectJ 的关系 因为AspectJ比较强大,所以spring能够解释与 AspectJ 5 相同的注解,并且它使用 AspectJ 提供的一个库来解析和匹配切入点(pointcut), 因为Aspectj 非常强大,所以spring aop借用甚至是复用了 aspectj的注解、注解解析相关部分的代码(没有依赖包),spring aop 代理机制是自己实现的,所以代码层面spring aop 和 aspectj 实际上没直接关系的。 阅读详情

相关推荐

spring和aspectj的aop实验

spring和aspectj的aop实验,详细内容可以移步至博客:https://mp.youkuaiyun.com/postedit/97750888

Spring 中基于AOP的@AspectJ

@AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格。通过在你的基于架构的 XML 配置文件中包含以下元素,@AspectJ 支持是可用的。 &lt;aop:aspectj-autoproxy/&gt; 如果需要使用该注解,需要包含一下几个包: - aspectjrt.jar - aspectjweaver.jar - asp...

soygrow的博客 360

Spring AOP之基于AspectJ注解总结与案例

Spring AOP之基于AspectJ注解总结与案例 ,具体效果和过程看博文 http://blog.youkuaiyun.com/evankaka/article/details/45394409

Spring的aspectj的AOP操作

(1)execution(*com.cn.aop.Book.add(..)) *代表任意修饰符 ..代表任何参数。execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)(4) 匹配所有save开头的方法 execution(*save*(..))1.切入点:实际增强的方法。使用表达式配置切入点。

bishe361的博客 1152

Spring 使用AspectJ 实现 AOP

Spring spectJ AOP 前置通知 后置通知 返回通知 异常通知 环绕通知

spring对AOP的支持(使用AspectJ进行AOP演示)

博文链接:https://shaqiang32.iteye.com/blog/201914

Spring AOP 和 AspectJ 有什么区别和联系?

首选 Spring AOP (95% 的场景)如果你的项目是基于 Spring 的,并且你只需要实现一些常见的横切关注点,如日志记录、声明式事务、安全检查、性能监控等,那么 Spring AOP 是你的最佳选择。它足够简单、强大,并且与生态系统完美集成。考虑 AspectJ (5% 的特殊场景)需要更强的能力:当你需要增强字段访问(例如实现数据脱敏)、构造函数(例如监控对象创建)或增强第三方库中不受 Spring 管理的代码时。追求极致性能。

专注于技术分享 761

别光看原理图了!手把手教你用Altium Designer搞定STM32F411最小系统的PCB布局(附电源/晶振/复位电路实战)

本文详细介绍了使用Altium Designer进行STM32F411最小系统PCB布局的实战技巧,涵盖电源分配网络优化、高速信号布线及系统级布局策略。通过规范的工程结构建立、关键设计规则预设和核心电路模块布局,帮助工程师提升PCB设计效率与信号完整性。特别针对STM32最小系统的电源、晶振和复位电路提供了专业解决方案。

weixin_42653691的博客 167

Spring基于AspectJ实现AOP操作

基于AspectJ实现AOP操作准备工作在项目工程里面引入 AOP 相关依赖。学会使用切入点表达式AOP 操作(AspectJ 注解)1、创建类,在类里面定义方法2、创建增强类(编写增强逻辑),在增强类里面,创建方法,让不同方法代表不同通知类型3、进行通知的配置4、配置不同类型的通知相同的切入点抽取有多个增强类多同一个方法进行增强,设置增强类优先级完全使用注解开发代码结构测试代码 Spring 框架一般都是基于 AspectJ 实现 AOP 操作。 需要注意的是:AspectJ 不是 Spring 组成部

『愚』的博客 6517

neruolib全脑建模计算框架

neurolib 是一个用python编写的全脑建模计算框架,也是可扩展的、允许轻松实现自定义神经质量模型,能够在介观尺度上表示脑区平均活动。

Rootfyx的博客 1147

避坑指南:LISFLOOD-FP模型数据单位、参数文件与results文件夹结果解析全攻略

本文详细解析了LISFLOOD-FP洪水模拟模型的关键应用环节,包括数据单位校验、参数文件优化及结果文件解读与可视化。特别针对常见的单位混淆问题,提供了从DEM到边界条件的全面校验方法,并深入剖析了.par参数文件的配置技巧,帮助用户避免模型崩溃和结果失真。

weixin_42533622的博客 236

[AOP] 2. AOP的两种实现-Spring AOP以及AspectJ

在接触Spring以及种类繁多的Java框架时,很多开发人员(至少包括我)都会觉得注解是个很奇妙的存在,为什么加上了@Transactional之后,方法会在一个事务的上下文中被执行呢?为什么加上了@Cacheable之后,方法的返回值会被记录到缓存中,从而让下次的重复调用能够直接利用缓存的结果呢?随着对AOP的逐渐应用和了解,才明白注解只是一个表象,在幕后Spring AOP/AspectJ做了大

不忘初心,好好沉淀 2万+

YOLOv11改进策略【模型轻量化】| 替换轻量化骨干网络:ShuffleNet V1

本文记录的是基于ShuffleNet V1的YOLOv11轻量化改进方法研究。ShuffleNet利用和操作降低计算成本,克服了现有先进架构在极小网络中因 1×1 卷积计算成本高而效率低的问题。相比一些传统的网络架构,能更好地。本文配置了原论文中和四种模型,以满足不同的需求。

Limiiiing的博客 1228

Spring AOP与 AspectJ 的区别

AOP(面向切面编程)通过分离日志、权限等非业务逻辑代码,解决重复编码问题。Spring AOP采用动态代理实现,仅支持Spring Bean的public方法,但存在同类调用失效等局限;AspectJ则通过字节码织入支持更广泛的切点,包括字段访问和构造方法等。实际开发中,Spring AOP适用于大多数场景,而AspectJ适合需要拦截非Spring对象或底层操作的特殊需求。两者本质区别在于代理机制与字节码修改的不同实现方式。

8年+后端老兵 | Java & Go 深度实践者 | 热衷于高并发、微服务与系统架构设计 持续输出干货,记录踩坑与成长,与你一起在技术的路上走得更远。 862

SAP Word 模板与 ABAP XML 数据流合并机制深度解析

Office Open XML 标准把一个.docx拆分成多个部件(document.xml、customXml\item1.xml 等),天然支持命名空间与 XPath;Word 在渲染时,会扫描<w:sdt>(结构化文档标签)与来确定绑定关系;在 ABAP 端,通过简单字符串替换与 XSLT 变换即可完成数据灌入,无需 COM Automation,安全且易于调试。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 371

抖音移动端Web用户主页视频列表爬虫实战:逆向加密参数与高频采集方案

App端Hook/抓包:需要安卓逆向、Xposed或Frida,门槛高且容易被风控。官方开放API:限制极多,几乎不开放用户级视频列表。PC端Web:页面加载方式繁杂,且大量依赖懒加载与内部状态。移动端Web(:接口相对稳定,加密逻辑集中,且适合使用Requests/HTTPSession模拟,无需渲染引擎。本文聚焦于移动端Web下的用户主页视频列表爬取,采用Python 3.11 + httpx + PyExecJS + 正则/JSON解析的组合,破解X-Bogus签名和_signature。

2201_76125261的博客 846

spring已经实现了aop,为什么还要用aspectj

spring已经实现了aop,为什么还要用aspectj? 1、是不是使用spring AOP的功能,都要引入这aspectj,是依赖关系? 2、如果2个是独立互不影响的东西,在平时的开发中,是不是更偏向于用aspectj,而不使用spring自己的AOP? 回答1: ①选择spring的AOP还是AspectJ? spring确实有自己的AOP。功能已经基本够用了,除非你的要在接口上动态代...

Dxd_zy的博客 4402

AI大模型探索之路-训练篇3:大语言模型全景解读

大规模语言模型(Large Language Models,LLM),也称大语言模型或大型语言模型,是一种由包含数百亿以上参数的深度神经网络构建的语言模型,通常使用自监督学习方法通过大量无标注文本进行训练。

寻道AI,探索AI无限可能! 6273

Spring AOP vs AspectJ AOP

本文探讨了Spring AOP与AspectJ AOP的区别。Spring AOP基于动态代理,支持方法级别PointCut,与Spring框架无缝集成,灵活且易于扩展;AspectJ AOP则基于静态代理,支持方法和属性级别PointCut,功能强大但配置复杂。两者各有优劣,适用于不同场景。合理选择AOP实现方式有助于提高代码的可维护性和可重用性。

技术铺掌柜 1324

华为OD机试 - 机器人活动区域(Java 双机位C卷 200分)

现有一个机器人,可放置于 M × N的网格中任意位置,每个网格包含一个非负整数编号。之后M行表示网格数值,每行N个数值(数值大小用k表示),数值间用单个空格分隔,行首行尾无多余空格。说明:图中绿色区域,相邻网格差值绝对值都小于等于1,且为最大区域,对应网格点数目为6。M、N、k均为整数,且1

学Java,找哪吒 915

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Spring整合AspectJ基于XML实现AOP

文章目录Spring整合AspectJ实现AOP介绍切入点表达式AspectJ 通知类型基于XML整合AspectJ目标类切面类Spring配置前置通知后置通知环绕通知抛出异常最终通知 Spring整合AspectJ实现AOP 前面我们已经学习了Spring AOP。那我们为什么还需要学习AspectJ,因为AspectJ 更为简单,更加方便。但是在我们的开发中我们不太使用Spring自身的对AO...

C. 969

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

上一篇: Java集合
下一篇: Spring JDBC Template简单使用
ZX9727
博客等级 码龄9年 0粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值