Spring-AOP

1.概念

AOP(Aspect Oriented Programming),意为“面向切片编程”,是Spring中一个重要的内容,其本质是动态代理,通过加入切片的方式,降低了各个业务逻辑之间的耦合度,让原生代码更加具有专一性

画个图方便理解:

我们一般使用AOP来向业务模块增加日志、缓存、安全功能等,下面的实例也是以上面这张图来完成的 

2.实现

UserService接口: 

public interface UserService {public void add();public void delete();public void update();public void select();}

 UserServiceImpl实现类:

public class UserServiceImpl implements UserService{@Overridepublic void add() {System.out.println("增加了一个用户");}@Overridepublic void delete() {System.out.println("删除了一个用户");}@Overridepublic void update() {System.out.println("修改了一个用户");}@Overridepublic void select() {System.out.println("查询了一个用户");}
}
  • 现在我想给这个实现类加一个日志功能,但是最好不要碰源码,这时就可以采用AOP
  • 实现AOP的方式有三种
  1. 采用Spring的API,如下:
2.1.Spring的API实现AOP 

 日志类(有前置日志和后置日志):

//一个前置的日志类
public class Log implements MethodBeforeAdvice {//method:要执行目标对象的方法//args:参数//target:目标对象@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {//**类的**方法被执行了System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");}
}
//一个后置的日志类
public class AfterLog implements AfterReturningAdvice {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("执行了"+method.getName()+"方法,返回值为:"+returnValue);}
}

导包:

    <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version></dependency>

 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/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!--注册bean--><bean id="userService" class="com.sun.service.UserServiceImpl"/><bean id="log" class="com.sun.log.Log"/><bean id="afterLog" class="com.sun.log.AfterLog"/><!--配置aop--><!--需要导入aop的约束:xmlns:aop="http://www.springframework.org/schema/aop"http://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd--><aop:config><!--切入点--><!--expression:表达式--><!--execution():表示切入点的位置,第一个参数表示返回值类型,*表示任意返回值,第二个参数表示这个包下任意一个方法,并且这些方法的参数也是任意的--><aop:pointcut id="pc" expression="execution(* com.sun.service.UserServiceImpl.*(..))"/><!--执行环绕--><!--把log这个bean放到上面写好的切入点中。--><aop:advisor advice-ref="log" pointcut-ref="pc"/><aop:advisor advice-ref="afterLog" pointcut-ref="pc"/></aop:config>
</beans>

测试类:

public class MyTest {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");//动态代理是代理的接口,所以转型的时候类型应该为接口,而不是实现类UserService userService = (UserService) context.getBean("userService");userService.add();}
}
2.2.自定义类来实现AOP

自定义的一个log类:

public class DiyLog {public void beforeLog(){System.out.println("----------程序运行前----------");}public void afterLog(){System.out.println("----------程序运行后----------");}
}

Spring的配置文件:

      <!--方式二:自定义类--><bean id="diy" class="com.sun.diy.DiyLog"/><aop:config><!--自定义切面(aspect)--><aop:aspect ref="diy"><!--切入点(pointcut)--><aop:pointcut id="point" expression="execution(* com.sun.service.UserServiceImpl.*(..))"/><!--增强(advice)--><aop:before method="beforeLog" pointcut-ref="point"/><aop:after method="afterLog" pointcut-ref="point"/></aop:aspect></aop:config>
  • 上面自定义的一个切面(aspect),相当于当我把切入点找到之后,往这个切入点注入的东西,就是一个切面,他往往是一个类(含有各种方法)
  • 而这个类中的各个方法就叫做一个个的增强(advice)
 2.3.使用注解实现AOP

自定义一个切片类:

@Aspect
public class Log {@Before("execution(* com.sun.service.UserServiceImpl.*(..))")public void beforeLog(){System.out.println("方法执行前");}@After("execution(* com.sun.service.UserServiceImpl.*(..))")public void afterLog(){System.out.println("方法执行后");}@Around("execution(* com.sun.service.UserServiceImpl.*(..))")//在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点//这个参数jointPoint表示所有方法的执行点,是用来被pointCut修饰的,被修饰之后我们就能知道哪些方法可以被织入advicepublic void around(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("环绕前");//执行方法Object proceed = joinPoint.proceed();System.out.println("环绕后");System.out.println(proceed);}}
  • @Aspect:表明这是一个切片
  • @Before:前置增强,参数是切入点
  • @After:后置增强,参数是切入点
  • @Around:环绕增强,参数是切入点

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

线性表--栈

1.什么是栈&#xff1f; 栈是一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除 操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出的原则。 压栈&#xff1a;栈的插入操作叫做进栈/压栈/入栈&#xff…

智能AI系统开发,专业软件硬件物联网开发公司,探索未来科技新纪元

在信息时代&#xff0c;人工智能&#xff08;AI&#xff09;、物联网等前沿技术日益受到人们的关注。智能AI系统、专业软件硬件物联网开发公司应运而生。今天&#xff0c;我们将向大家介绍一家位于XX城的专业公司&#xff0c;致力于智能AI系统开发和软件硬件物联网领域的创新研…

华清远见作业第三十二天——C++(第一天)

思维导图&#xff1a; 提示并输入一个字符串&#xff0c;统计字符中大写、小写个数、空格个数以及其他字符个数要求使用C风格完成。 代码&#xff1a; #include <iostream> #include<array> using namespace std;int main() {string str;cout << "请输…

用大模型训练实体机器人,谷歌推出机器人代理模型

谷歌DeepMind的研究人员推出了一款&#xff0c;通过视觉语言模型进行场景理解&#xff0c;并使用大语言模型来发出指令控制实体机器人的模型——AutoRT AutoRT可有效地推理自主权和安全性&#xff0c;并扩大实体机器人学习的数据收集规模。在实验中&#xff0c;AutoRT指导超过…

K8s 安装部署-Master和Minion(Node)文档

K8s 安装部署-Master和Minion(Node)文档 操作系统版本&#xff1a;CentOS 7.4 Master &#xff1a;172.20.26.167 Minion-1&#xff1a;172.20.26.198 Minion-2&#xff1a;172.20.26.210&#xff08;后增加节点&#xff09; ETCD&#xff1a;172.20.27.218 先安装部署ETC…

pytorch 实现中文文本分类

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客&#x1f366; 参考文章&#xff1a;365天深度学习训练营&#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制]\n&#x1f680; 文章来源&#xff1a;[K同学的学习圈子](https://www.yuque.com/mi…

WPF自定义圆形百分比进度条

先看效果图 1.界面代码 <UserControl x:Class"LensAgingTest.CycleProcessBar1"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc"http://schemas.op…

Java研学-代理模式

一 概述 1 分类 静态代理&#xff1a;在程序运行前就已经存在代理类的字节码文件&#xff0c;代理对象和真实对象的关系在运行前就确定了。&#xff08;代理类及对象要自行创建&#xff09;   动态代理&#xff1a;代理类是在程序运行期间由 JVM 通过反射等机制动态的生成的…

朴素贝叶斯分类算法

1.分类算法 分类算法是有监督学习的一个核心问题&#xff0c;他从数据中学习一个分类决策函数或分类模型&#xff0c;对新的输入进行预测&#xff0c;输出变量取有限个离散值。 &#x1f30d;分类算法的内容是要求给定特征&#xff0c;让我们得出类别。 那么如何由指定特征&…

Asp.Net Core 获取应用程序相关目录

在ASP.NET Core中&#xff0c;可以通过以下三种方式获取应用程序所在目录&#xff1a; 1、使用AppContext.BaseDirectory属性&#xff1a; string appDirectory AppContext.BaseDirectory; 例如&#xff1a;D:\后端项目\testCore\test.WebApi\bin\Debug\net6.0\ 2、使用…

Leetcode刷题笔记题解(C++):LCR 153. 二叉树中和为目标值的路径

思路&#xff1a;利用回溯的思想&#xff0c;回溯的退出条件为当前节点为空&#xff0c;是符合路径的判断条件为路径和为目标值且叶子节点包含了&#xff0c;代码如下&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *…

【C++】入门基础

前言&#xff1a;C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;因此从今天开始们将进入&#xff23;的学习。 &#x1f496; 博主CSDN主页:…

《动手学深度学习(PyTorch版)》笔记4.5

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…

ES文档索引、查询、分片、文档评分和分析器技术原理

技术原理 索引文档 索引文档分为单个文档和多个文档。 单个文档 新建单个文档所需要的步骤顺序&#xff1a; 客户端向 Node 1 发送新建、索引或者删除请求。节点使用文档的 _id 确定文档属于分片 0 。请求会被转发到 Node 3&#xff0c;因为分片 0 的主分片目前被分配在 …

微信小程序(十七)自定义组件生命周期(根据状态栏自适配)

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.获取手机状态栏的高度 2.验证attached可以修改数据 3.动态绑定样式数值 源码&#xff1a; myNav.js Component({lifetimes:{//相当于vue的created,因为无法更新数据被打入冷宫created(){},//相当于vue的mount…

【JS基础】事件对象event、环境对象this、事件的高级操作

文章目录 一、事件对象1.1 事件对象是什么&#xff1f;1.2 使用方法 二、环境对象this以及回调函数2.1 它是什么&#xff1f;2.2 演示示例 三、事件的高级操作3.1 事件流3.2 事件捕获3.3 事件冒泡以及阻止冒泡3.4 事件解绑3.5 mouseover和mouseenter事件的区别3.6 事件委托它是…

HTML新手教程

HTML入门 教程&#xff1a;【狂神说Java】HTML5完整教学通俗易懂_哔哩哔哩_bilibili 一.初识HTML HyperTextMarkupLanguage&#xff08;超文本标记语言&#xff09; 超文本包括&#xff1a;文字、图片、音频、视频、动画。 HTML5的优势 世界知名浏览器厂商对HTML5的支持市场的…

解决WinForms跨线程操作控件的问题

解决WinForms跨线程操作控件的问题 介绍 在构建Windows窗体应用程序时&#xff0c;我们通常会遇到需要从非UI线程更新UI元素的场景。由于WinForms控件并不是线程安全的&#xff0c;直接这样做会抛出一个异常&#xff1a;“控件’control name’是从其他线程创建的&#xff0c;…

每日OJ题_算法_二分查找⑦_力扣153. 寻找旋转排序数组中的最小值

目录 力扣153. 寻找旋转排序数组中的最小值 解析代码 力扣153. 寻找旋转排序数组中的最小值 153. 寻找旋转排序数组中的最小值 - 力扣&#xff08;LeetCode&#xff09; 难度 中等 已知一个长度为 n 的数组&#xff0c;预先按照升序排列&#xff0c;经由 1 到 n 次 旋转 后…

node学习过程中的终端命令

冷的哥们手真tm冷&#xff0c;打字都是僵的&#xff0c;屮 目录 一、在学习nodejs过程中用到的终端命令总结 一、在学习nodejs过程中用到的终端命令 node -v nvm install 20.11.0 nvm list nvm list available nvm on nvm -v nvm use 20.11.0 node加要运行的js文件路径 ps&a…