Javaee Spring基于XML的AOP开发

news2024/11/24 4:56:49

快速入门

1. 导入 AOP 相关坐标
2. 创建目标接口和目标类(内部有切点)
3. 创建切面类(内部有增强方法)
4. 将目标类和切面类的对象创建权交给 spring
5. applicationContext.xml 中配置织入关系
6. 测试代码

项目结构:

 

AccountService 创建目标接口
package wwx.aop;

public interface AccountService {
    public void save();
    //AccountService,Spring,AOPTest,AccountServiceImpl,MyAspect
}
AccountServiceImpl 创建目标类

package wwx.aop;
//目标类
public class AccountServiceImpl implements AccountService {
    @Override
    public void save() {
        System.out.println("save方法执行了。。。");
        int num=10/0;//0不能作分母,有异常,异常通知才会执行
    }
}
MyAspect 创建切面类(内部有增强的方法)

package wwx.aop;
import org.aspectj.lang.ProceedingJoinPoint;

import java.util.Date;

//切面类
public class MyAspect {
    //前置通知
    public void before() {
        Date date = new Date();
        System.out.println("前置通知:"+date);
    }
    //后置通知
    public void afterreturning(){
        System.out.println("后置通知:方法执行完毕");
    }
    //环绕通知
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        //记录方法执行的时间
        long time01 = System.currentTimeMillis();
        System.out.println("方法执行前");
        //切入点方法执行
        joinPoint.proceed();
        //记录方法执行后的时间
        long time2 = System.currentTimeMillis();
        System.out.println("方法执行后");
        //后-前
        System.out.println("环绕通知:方法执行的时间"+(time2-time01));
    }
    //异常通知
    public void throwing(){
        System.out.println("异常通知:系统升级中...");
    }
    //最终通知
    public void after(){
        System.out.println("最终通知:我一定会执行");
    }
}
Spring 将目标类和切面类的对象创建权交给 spring,在 spring配置文件中配置织入关系

<?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 id="accountService" class="wwx.aop.AccountServiceImpl"></bean>
    <!--配置切面类-->
    <bean id="myAspect" class="wwx.aop.MyAspect"></bean><!--这行,是把创建切面类的权利交给Spring-->
    <!--私有方法一旦执行,spring就会监听到,一旦监听到就会根据类的接口
    去整一个代理对象,然后根据通知的类型,去对私有方法进行增强
     -->
    <!--配置aop的织入-->
     <aop:config>
     <!--配置切面:切入点+通知-->
    <aop:aspect ref="myAspect"><!--指定myAspect作为切面类-->
 <!--第1种织入方式-->      
        <!--前置通知-->
        <aop:before method="before" pointcut="execution(public void wwx.aop.AccountServiceImpl.save())"></aop:before>  

        <!--后置通知-->
        <aop:after-returning method="afterreturning" pointcut-ref="pt1"></aop:after-returning>
<!--第2种织入方式-->
    <aop:pointcut id="pt1" expression="execution(public void
wwx.aop.AccountServiceImpl.save())"/>  

        <!--环绕通知-->
        <aop:around method="around" pointcut-ref="pt1"></aop:around>
        <!--异常通知-->
        <aop:after-throwing method="throwing" pointcut-ref="pt1"></aop:after-throwing>
        <!--最终通知-->
         <aop:after method="after" pointcut-ref="pt1"></aop:after>
    </aop:aspect>
     </aop:config>



</beans>
AOPTest 测试代码
package wwx.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPTest {
   @Test
    public void test01()
   {
       //加载配置文件
       ApplicationContext app = new ClassPathXmlApplicationContext("Spring.xml");
       //获得Bean
       AccountService accountService = (AccountService) app.getBean("accountService");
       //执行方法
       accountService.save();

   }
}

目标类中有异常时: 

 目标类中无异常时: 

 

2.2 切点表达式的写法
表达式语法:
execution ([ 修饰符 ] 返回值类型 包名 . 类名 . 方法名 ( 参数 ))

 

访问修饰符可以省略
返回值类型、包名、类名、方法名可以使用星号 * 代表任意
包名与类名之间一个点 . 代表当前包下的类,两个点 .. 表示当前包及其子包下的类
参数列表可以使用两个点 .. 表示任意个数,任意类型的参数列表
execution ( public void com . lzw . aop . Service . method ())
execution ( void com . lzw . aop . Service . * (..))
execution ( * com . lzw . aop . * . * (..))
execution ( * com . lzw . aop .. * . * (..))
execution ( * * .. * . * (..))
2.3 通知的类型
通知的配置语法:
< aop : 通知类型 method = 切面类中方法名 ” pointcut = 切点表达式 "></aop: 通知类型 >

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/448379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据库】MySQL数据约束和表关系详解

目录 1.数据库约束 1.1约束类型 1.2NULL约束 1.3UNIQUE&#xff1a;唯一约束 1.4DEFAULT&#xff1a;默认值约束 1.5PRIMARY&#xff1a;主键约束 1.6FOREIGH KEY:外键约束 2.表的关系 2.1一对一 2.2一对多 2.3多对多 1.数据库约束 数据库中的数据保存在数据表中&am…

数据库基础篇 《9. 子查询》

目录 1. 需求分析与问题解决 1.1 实际问题 1.2 子查询的基本使用 ​编辑1.3 子查询的分类 分类方式1&#xff1a;我们按内查询的结果返回一条还是多条记录&#xff0c;将子查询分为 单行子查询 、 多行子查询 。 分类方式2&#xff1a; 我们按内查询是否被执行多次&#x…

4WE10D50型力士乐液压阀规格

安装位置 可选择&#xff0c;方向阀最好水平安装&#xff01;对于阀品种&#xff0c;如 &#xff0d; 不带阀芯对中弹簧 &#xff0d; 或带下垂电磁铁 其他安装位置能够导致功能失常或违反有关的技朮规定。 带泄油口的压力开关的安装位置必须选择&#xff0c;使它的泄油口…

Redis源码分析之网络模型

Redis网络模型 阅读源码的初衷Redis源码阅读 阅读源码的初衷 很多网上解释这个Redis为啥这么块&#xff1f;都会说Redis这么快的原因会有一个Redis才用了单线程&使用了多路io复用来检查io事件&#xff0c;单线程可以避免多线程对资源的竞争。如果我们使用了多线程那么就需…

Revit中栏杆扶手、坡道的绘制及插件太多问题

一、在Revit中栏杆与扶手的绘制方法有两种&#xff1a; ①绘制路径 ②放置在主体上 二、执行方式 功能区&#xff1a;“建筑”选项卡“楼梯坡道”面板“栏杆扶手”下拉菜单“绘制路径”。 三、绘制技巧 首先我们一起来看看如何设置栏杆扶手属性。 第一步&#xff1a;设置属…

【vue3学习系列】对比vue2生命周期做了哪些改变,vue3初学者快来看看

文章目录 前言官方生命周期图分析去除beforeCreate与createdsetup代替created其他钩子只是改了名称 剔除vue2后的生命周期图其他钩子函数keepalive错误捕获其他的一些钩子去官方文档看看即可 前言 看了下官方的生命周期的说明&#xff0c;感觉讲的不算太清晰&#xff0c;所以个…

C++ 内联函数(inline)

内联函数&#xff1a;就是在函数前加inline 让函数在调用的地方直接展开 可是内联函数有什么作用呢&#xff1f;&#xff1f; 我们都知道&#xff0c;如果调用一个函数的话&#xff0c;会建立栈帧&#xff0c;在建立栈帧的时候会进行压栈等一系列操作。 而内联函数会在调用的…

Nginx和tomcat反向代理

七层反向代理 实验准备&#xff1a;准备三台虚拟机 192.168.146.20 tomcat&#xff08;两个&#xff09; 192.168.146.30 tomcat 192.168.146.50 七层反向代理&#xff08;nginx&#xff09; 部署虚拟机192.168.146.20&#xff08;两个tomcat已部署完毕&#xff09; …

SwiftUI 4.0(iOS 16)极简实现一个美美哒的多选 Toggle 按钮组

概览 在 SwiftUI 4.0 之前&#xff0c;想要实现如下效果的多选/全选 Toggle 按钮组是要写不少行代码滴&#xff1a; 不过&#xff0c;在 iOS 16 之后我们仅用1行代码即可搞定以上所有&#xff01;在某些场合下这非常有用哦。 在本篇博文中&#xff0c;我们就来看看如何实现它…

2023年的深度学习入门指南(6) - 剪枝和量化

2023年的深度学习入门指南(6) - 剪枝和量化 从这一节开始&#xff0c;我们要准备一些技术专项了。因为目前大模型技术还在快速更新迭代中&#xff0c;各种库和实现每天都在不停出现。因为变化快&#xff0c;所以难免会遇到一些问题。对于细节有一定的把握能力起码可以做到出问…

5.1 数值微分

学习目标&#xff1a; 作为数值分析的基础内容&#xff0c;我建议你可以采取以下步骤来学习数值微分&#xff1a; 掌握微积分基础&#xff1a;数值微分是微积分中的一个分支&#xff0c;需要先掌握微积分基础知识&#xff0c;包括导数、极限、微分等。 学习数值微分的概念和方…

Scillus | 来吧!它可以大大简化你的Seurat分析流程哦!~(二)(高级可视化)

1写在前面 不知道大家那里天气热了没有&#xff0c;苦逼的我虽然“享受”着医院的恒温&#xff0c;但也并没有什么卵用&#xff0c;毕竟我只是个不可以生锈的“小螺丝”。&#x1f972; 上期介绍了Scillus包的基本功能&#xff0c;如何进行数据的预处理及其可视化。&#x1f92…

分享github上比较热门的ChatGPT项目,值得收藏

&#x1f517; 运行环境&#xff1a;chatGPT &#x1f6a9; 撰写作者&#xff1a;左手の明天 &#x1f947; 精选专栏&#xff1a;《python》 &#x1f525; 推荐专栏&#xff1a;《算法研究》 #### 防伪水印——左手の明天 #### &#x1f497; 大家好&#x1f917;&#x1f9…

Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)

Elasticsearch painless脚本 1.什么是painless2.painless的特性3.使用kibana进行准备操作3.1 使用kibana创建索引和映射3.2 使用kibana添加测试数据 4.使用painless执行查询操作关于脚本查询须知4.1 字段查询脚本4.1 排序查询脚本 5.如何使用painless执行更新操作关于脚本查询须…

Spring Security 04 自定义认证

登录⽤户数据获取 SecurityContextHolder Spring Security 会将登录⽤户数据保存在 Session 中。但是&#xff0c;为了使⽤⽅便, Spring Security 在此基础上还做了⼀些改进&#xff0c;其中最主要的⼀个变化就是线程绑定。当⽤户登录成功后,Spring Security 会将登录成功的⽤户…

Node内置模块 【crypto加密模块】

文章目录 &#x1f31f;前言&#x1f31f;crypto加密模块&#x1f31f;Crypto模块介绍&#x1f31f;Hash算法&#x1f31f;Hash算法介绍&#x1f31f;Hash算法之MD5&#x1f31f;算法简介&#x1f31f;MD5加密使用 &#x1f31f;Hash算法之SHA1&#x1f31f;算法简介&#x1f3…

二叉树经典题题解

目录 &#x1f345;1.单值二叉树&#x1f345; &#x1f349; 2.相同的树&#x1f349; &#x1f34a;3.对称二叉树&#x1f34a; &#x1f34e;4.另一颗树的子树&#x1f34e; &#x1f34f;5.翻转二叉树&#x1f34f; &#x1f351;6.平衡二叉树&#x1f351; &#x1f3…

【LeetCode: 1027. 最长等差数列 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

SHELL的脚本编辑与运行

目录 1.编写脚本for1.sh,使用for循环创建20账户&#xff0c;账户名前缀由用户从键盘输入&#xff0c;账户初始密码由用户输入&#xff0c;例如&#xff1a;test1、test2、test3、、test10 a.编辑脚本 b.运行脚本 c.进行检验 2.编写脚本for2.sh,使用for循环&#xff0c;通过…

如何把aac转化为mp3,4个处理方法教给你

一般情况下&#xff0c;将 AAC 文件转换为 MP3 文件有以下几种情况&#xff1a;设备不兼容&#xff1a;AAC 格式通常用于苹果设备上。如果您想在其他设备上播放音频文件&#xff0c;如 Android 手机、MP3 播放器等&#xff0c;就需要将其转换为 MP3 格式。需要更好的兼容性&…