Spring:基于xml和注解的aop

2023-10-27

1、导入坐标

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>

<!--用于解析切入点表达式的jar包-->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
</dependency>

2、建立通知类

将方法(主要是业务逻辑层的方法)中的共性代码抽取出来放到通知类中统一管理。

3、配置通知

配置文件中添加aop的约束。先配置ioc(spring的其它功能都需要基于ioc),再配置aop。

<?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">

    <!--先配置service的ioc-->
    <bean id="accountService" class="cao.zhanpeng.service.impl.AccountServiceImpl"/>

    <!--配置通知类的ioc-->
    <bean id="log" class="cao.zhanpeng.utils.Logger"/>

    <!--开始配置aop-->
    <aop:config>
        <!--配置切面,id表示该切面唯一标识符,ref用于指定通知类bean的id-->
        <aop:aspect id="logShow" ref="log">
            <!--配置通知类型,aop:before表示前置通知
            method指定通知类中哪个方法是前置通知(哪个是通知?)
            pointcut指定切入点表达式,表示对业务层的哪些方法进行通知(对谁通知?)
            -->
            <aop:before method="printLog" pointcut="execution(public void cao.zhanpeng.service.impl.AccountServiceImpl.saveMoney())"/>
        </aop:aspect>
    </aop:config>
</beans>

可以将切入点表达式独立出来

<!--将切入点表示式独立出来
如果放在切面内,只能当前切面引用
如果放在切面外,可以多个切面共用
-->
<aop:pointcut id="pt1" expression="execution(* cao.zhanpeng.service.impl.*.*(..))"/>
<!--再引用-->
<aop:before method="printLog" pointcut-ref="pt1"/>

切入点表达式

  • 关键字:execution(表达式)
  • 表达式:访问修饰符 返回值 通知目标类的全类名.方法名(参数列表)
  • 访问修饰符可以省略
  • 通常会将范围锁定到业务层的实现类包下
<!--星号表示任意通配符,双点..可以表示任意数量的通配符-->
* com.zanpng.service.impl.*.*(..)

 全通配写法如下(了解)

* *..*.*(..)

通知类型

aop:before,前置通知
aop:after-returning,后置通知
aop:after-throwing,异常通知,和后置通知互斥
aop:after,最终通知
aop:around,环绕通知

注解实现aop

1、配置环境

需要在applicationContext.xml文件导入context约束,配置ioc注解扫描,并直接使用以下标签开启aop注解。

<aop:aspectj-autoproxy/>

2、使用注解

在通知类上除了写上ioc注解,还要加上@Aspect注解,表示当前类是一个通知类。还要在对应的方法上使用如下注解

@Before注解,前置通知
@AfterRunning注解,后置通知
@AfterThrowing注解,异常通知
@After注解,最终通知
@Around注解,环绕通知

定义一个空语句体的方法,使用@Pointcut注解传递切入点表达式,并且在其他注解中传递该方法,注意括号别忘了。

@Pointcut("execution(* cao.zhanpeng.service.impl.*.*(..))")
private void pt1(){}

@Before("pt1()")
public void beforePrintLog(){……}

在使用注解实现aop时,spring会出现一些执行顺序上的问题。所以如果要用注解,还是使用环绕通知来手动指定较好。环绕通知需要自己实现动态代理的代码,根据位置手动指定某个通知为何种类型。

  • spring框架提供了一个接口ProceedingJoinPoint,该接口可以作为通知类中环绕通知方法的参数,执行时spring会自动帮我们创建实现类对象,比如叫pjp。
  • pjp.getArgs()可以获取方法执行所需的参数。
  • ProceedingJoinPoint接口中有一个方法proceed(),此方法可以明确调用切入点方法(对应反射中的invoke方法),传递获取的参数即可。
@Around("pt1()")
public Object aroundPrintLog(ProceedingJoinPoint pjp){
    Object rtValue = null;
    try{
        Object[] args = pjp.getArgs();
        ……前置通知代码块……
        rtValue = pjp.proceed(args)
        ……后置通知代码块……
    }catch{
        ……异常通知代码块……
    }finally{
        ……最终通知代码块……
    }
}

有了环绕通知,就不能让其他的通知起作用了,否则会产生冲突。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring:基于xml和注解的aop 的相关文章

  • Spring:基于xml和注解的aop

    1 导入坐标
  • SPRINGBOOT的常用注解

    Spring是用来管理业务层的框架 通过集成持久层框架也可以用来管理持久层 主要的两大功能是控制反转和面向切面编程 主要目的是实现程序的解耦 SpringMVC是用来管理控制层的框架 主要是实现和WEB的交互 注意不要直接在控制层编写业务代
  • FASTJSON和JACKSON基本使用

    Json是一种轻量级的数据交换格式 采用一种 键 值 对的文本格式来存储和表示数据 在系统交换数据过程中常常被使用 是一种理想的数据交换语言 在使用Java做Web开发时 不可避免的会遇到Json的使用 JSON形式与语法 JSON对象 我
  • mybatis:基于xml的环境搭建

    前期准备 创建好数据库表对应的实体类 实体类最好实现序列化接口Serializable 创建好实体类对应的dao层接口 每一个实体类都会对应一个dao接口 每一个dao接口也都对应一个配置文件 mybatis中 约定俗成地将持久层的操作接口
  • 带按钮的自定义 MKAnnotation 标注气泡

    我正在开发应用程序 用户通过 GPS 进行本地化 然后询问他是否位于特定位置 为了确认这一点 标注气泡会立即呈现给他 询问他是否在特定位置 As there is alot of similar questions I was able t
  • Frame.__init__ 是做什么的?

    在下面的代码中 第 5 行是什么Frame init 做 有人可以解释一下它背后的概念吗 多谢 from Tkinter import class AppUI Frame def init self master None Frame in
  • 我的 UIButton 的位置在所有模拟器中都不同

    我在一个项目下 我使用代码 不是通过故事板 在视图控制器的底部创建了一个 uibutton 但是当我运行我的应用程序时 我的 uibutton 放置在不同的位置 例如在 iphone 5 6 模拟器中某个位置 在 4s 中 ipad 模拟器
  • 如何在 Java 中解析和验证 WebSocket 帧?

    我用Java编写了一个WebSocket帧解码器 private byte decodeFrame byte rawIn int maskIndex 2 byte maskBytes new byte 4 if rawIn 1 byte 1
  • 恒定 FPS Android OpenGLES

    你好安卓开发者 我正在 Eclipse 中使用 OpenGLES 1 0 为 Android 开发一个简单的游戏 我使用 Samsung Galaxy S2 Android 2 3 作为开发设备 我有一个关于双核和使帧速率恒定的问题 因此
  • 添加 TabBarController 作为视图的子视图

    当我的应用程序启动时 我正在加载启动屏幕 然后我想加载一个TabBarController 它是ViewControllers 但是 我的 TabBarController 窗口无法缩放到屏幕尺寸 底部的 TabBar 的 3 4 可能被切
  • 如何在 iOS 的照片拼贴中滑动时调整视图大小?

    我正在编写一个照片编辑器演示 用户可以水平或垂直滑动以将视图分割为他们想要的许多小视图 然后用户可以拖动每个视图的边框来重新调整视图的大小 问题是我不知道如何制作照片拼贴 用户可以拖动视图边框来改变视图的大小 我认为每个白色边框 如下图所示
  • boundingRectWithSize 不考虑自动换行

    我创建一个 UITextView 向其中添加文本 然后将其放入视图中 使用容器 UITextView lyricView UITextView alloc initWithFrame screen lyricView text NSStri
  • 是否可以阻止您的网站在另一个域的框架集和 IFrame 内运行?

    最近我们遇到了一个问题 其他网站在一个框架集中运行我们的电子商务网站 而我们的网站 附加了违规者附属 ID 是单个全宽框架中的唯一内容 所以本质上它看起来和感觉就像我们的网站 其 URL 位于顶部 我们可以切断他们的会员 ID 这会让他们这
  • 如何在android中制作随机帧动画?

    我有许多动画图像 帧 例如 image 1 image 2 和 image 3 我想在我的应用程序中使用这个动画图像 所以我尝试了
  • 如何在 Tkinter 中获得带有滚动条的框架?

    我想要一个Frame 用户可以根据应用程序的需要添加任意数量的文本字段 该应用程序以一个文本字段和该文本字段下方的一个按钮开始 当用户按下按钮时 新的文本条目将添加到第一个文本条目下方 这可能会重复无数次 在窗口的中间 会有一个Text小部
  • 如何从框架中获取用户输入并保存到txt文件中?

    我的程序运行如下 我有一个带有添加按钮 保存按钮和选项卡控件的表单 当单击表单中的添加按钮时 选项卡控件将添加更多选项卡项目 tabitem 基本上是从 myframe 添加的 其中包括用户在 TEdit 中键入的值 我想要实现的是当我点击
  • 将预览帧转换为位图

    我知道这个主题已经在黑板上出现过很多次了 但无论如何我都无法让它发挥作用 我想将预览中的视图帧保存为 jpeg 文件 它看起来或多或少 代码被简化 没有额外的逻辑 异常等 像这样 public void onPreviewFrame byt
  • 获取嵌套在 JavaScript 中的 Frame 内的 iframe 内的元素值?

    我的 php 主页面有 2 个框架 第二个框架内有 iframe 我想从第一帧访问 iframe 文档上元素的值 我尝试这样 var frame1 parent frames 1 var frame2 frame1 document get
  • 当 UIView 通过自动布局调整大小时,会调用什么方法?

    我有一个图像视图 我通过在子类中覆盖以下内容来实现圆角 void setFrame CGRect frame super setFrame frame self layout setCornerRadius frame size width
  • Tkinter 框架滚动条

    我的目标是向其中有多个标签的框架添加一个垂直滚动条 一旦框架内的标签超过框架的高度 滚动条就会自动启用 经过一番搜索 我发现this https stackoverflow com questions 3085696 adding a sc

随机推荐

  • Servlet 清除Cookie 方法

    一 删除已知名称的Cookie 方案 重新建立同名立即删除类型的Cookie Cookie newCookie new Cookie username null 假如要删除名称为username的Cookie newCookie setMa
  • 工作流简介及其6种常用的工作流引擎

    先说说四个非PetriNet调度算法的开源引擎 4 OBE的引擎调度机制 4 Shark的引擎调度机制 5 OSWorkflow的引擎执行机制 6 JBpm的引擎执行机制 6 再说说两个PetriNet调度算法的开源引擎 9 YAWL的引擎
  • 图说函数模板右值引用参数(T&&)类型推导规则(C++11)

    图说函数模板右值引用参数 T 类型推导规则 C 11 见下图 规律总结 只要我们传递一个基本类型是A 的左值 那么 传递后 T的类型就是A 形参在函数体中的类型就是A 只要我们传递一个基本类型是A的右值 那么 传递后 T的类型就是A 形参在
  • 解析Cloudsim中,获取SLA指标的函数:getSlaMetrics()

    protected static Map
  • 如何使用 Humata.ai:快速理解和总结文献

    链接 Humata 简介 Humata ai 是一个人工智能驱动的文献阅读助手 可以帮助用户快速理解和总结文献 它可以提取文献的关键信息 并以简洁易懂的语言生成摘要 此外 Humata ai 还可以回答用户关于文献的问题 帮助用户深入理解文
  • 选择一家公司看哪些条件

    1 薪资 公司谈的工资都是税前 一般我会认为年薪工资指的就是一年的税前收入 如果有加班费可以把加班费也算上 每月加班时间是有上限的 可以根据个人习惯计算 然后是年终奖 则税前年薪 税前基本工资 加班费 年终奖 你看工资银行卡一年的薪资到账记
  • xcode报错:Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/b

    今天使用xcode编译工程发现一个问题 这里记录一下防止忘记 xcode报错 Command Applications Xcode app Contents Developer Toolchains XcodeDefault xctoolc
  • 本地部署Stable Diffusion

    效果 遇到的坑 报错 RuntimeError LayerNormKernelImpl not implemented for Half 解决方案 产生报错的原因是因为显卡不支持half float的数据类型 所以在启动项set COMMA
  • 微信小程序(由浅到深)

    文章目录 一 项目基本配置 1 项目组成 2 常见的配置文件解析 3 app json全局的五大配置 4 单个页面中的page配置 5 App函数 6 tabBar配置 二 基本语法 事件 单位 1 语法 2 事件 3 单位 三 数据响应式
  • python语法-pyspark实战(数据输入)

    python语法 pyspark实战 数据输入 1 演示通过pyspark代码加载python对象数据 基本数据结构 转为RDD对象 即数据输入 parallelize 方法 演示通过pyspark代码加载数据 即数据输入 from pys
  • varchar2 汉字长度问题

    转载于 https www cnblogs com yangxia test archive 2013 08 07 3242775 html Oracle定义varchar2 类型存储汉字的长度问题 varchar2最大是4000字节 那么
  • 使用 Iptables 命令详细图文教程

    目录 一 防火墙管理工具 二 Iptables 2 1 策略与规则链 2 2 基本的命令参数 2 2 1 在 iptables 命令后添加 L 参数查看已有的防火墙规则链 2 2 2 在 iptables 命令后添加 F 参数清空已有的防火
  • 【Altium designer】定义PCB外形并开槽

    1 PCB自定义外形 项目中经常会用到异形的PCB 需要先在keep out画出PCB外形 也可以直接从cad里面导到AD里面 要注意单位长度的转换 然后框选中keep out的线条 按下快捷键D S D 设计 gt 板子形状 gt 按照选
  • python-爬虫 抓取美食板块商家数据

    import pprint import requests import csv import re url http meishi meituan com i api channel deal list headers User Agen
  • 【odoo15】给用户设置菜单可见的权限与权限组

    设置mykid菜单的可见权限 设置权限后 操作方法 设置 gt 用户和公司 gt 组群 gt 创建组群 test group 技术 gt 用户界面 菜单项目 gt 搜索要添加到组群的菜单 mykid 把用户添加到组群中 刷新后admin这个
  • PageHelper分页插件使用

    分页插件PageHelper MyBatis没有分页功能 需要手动编写LIMIT语句 可以使用第三方的插件来对功能进行扩展 分页助手PageHelper是将分页的复杂操作进行封装 使用简单的方式即可获得分页的相关数据 PageInfo Pa
  • 将代码托管到Github

    1 进入Github网站 https github com 选择登录 sign in 或注册 sign up 如图所示 2 下载桌面程序 GitHub Desktop 网址 https desktop github com 按提示默认安装即
  • pytorch,numpy两种方法实现nms类间+类内

    类间 也就是不同类之间也进行nms 类内 就是只把同类的bboxes进行nms numpy实现 nms类间 类内 import numpy as np 类间nms def nms bboxes scores thresh x1 y1 x2
  • python os.walk 指定遍历深度_安全检查中...

  • Spring:基于xml和注解的aop

    1 导入坐标