Spring AOP的几种实现方式
1.通过注解实现
1.1导入依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.6.RELEASE</version></dependency>
1.2定义注解
import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TestAnnotation{
}
1.2定义切面类
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;/*
* 切面类
**/
@Aspect
@Component
public class AnnotationAspect {// 定义一个切点:所有被RequestMapping注解修饰的方法会织入advice@Pointcut("@annotation(TestAnnotation)")private void advicePointcut() {}/** 前置通知**/@Before("advicePointcut()")public void before() {System.out.println("annotation前置通知");}@After("advicePointcut()")public void after() {System.out.println("annotation后置通知");}@AfterReturning(pointcut = "advicePointcut()")public void afterReturning() {System.out.println("annotation后置返回通知");}@AfterThrowing(pointcut = "advicePointcut()", throwing = "ex")public void afterThrowing(Exception ex) throws Exception {System.out.println("annotation异常通知");System.out.println(ex.getMessage());}@Around("advicePointcut()")public Object around(ProceedingJoinPoint pjp) throws Throwable {Object proceed = null;if (!"".equals("admin")) {System.out.println("annotation环绕前置");proceed = pjp.proceed(pjp.getArgs());System.out.println("annotation环绕后置");}return proceed;}
}
2.jdk代理注解方式
2.1.定义接口
public interface TargetInteface {void method1();void method2();int method3(Integer i);
}
2.2.实现接口
public class Target implements TargetInteface{/** 需要增强的方法,连接点JoinPoint**/public void method1() {System.out.println("method1 running ...");}public void method2() {System.out.println("method2 running ...");}public int method3(Integer i) {System.out.println("method3 running ...");return i;}
}
2.3.定义通知
public class TargetAdvice implements MethodInterceptor, MethodBeforeAdvice, AfterReturningAdvice {/** 通知/增强**/@Overridepublic Object invoke(MethodInvocation methodInvocation) throws Throwable {System.out.println("前置环绕通知");Object proceed = methodInvocation.proceed();System.out.println("后置环绕通知");return proceed;}@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("后置返回通知");}@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("前置通知");}
}
2.4.书写配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean id="target" class="com.heaboy.aopdemo.aop.Target"/><bean id="targetAdvice" class="com.heaboy.aopdemo.aop.TargetAdvice"/><bean id="targetProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="target"/> <!--被代理的类--><property name="interceptorNames" value="targetAdvice"/> <!--如果用多种增强方式,value的值使用逗号(,)分割--><property name="proxyTargetClass" value="false"/><property name="interfaces" value="com.heaboy.aopdemo.aop.TargetInteface"/> <!--target实现的接口--></bean>
</beans>
2.5启动测试
public class AopTest {public static void main(String[] args) {ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-aop.xml");TargetInteface targetProxy = (TargetInteface) appCtx.getBean("targetProxy");targetProxy.method1();print(targetProxy);}
}
3.cglib配置文件方式
3.1.定义被代理的类
public class Target {public void method1() {System.out.println("method1 running ...");}public void method2() {System.out.println("method2 running ...");}/** 连接点JoinPoint**/public int method3(Integer i) {System.out.println("method3 running ...");int i1 = 1 / i;return i;}
}
3.2.定义Aspect
import org.aspectj.lang.ProceedingJoinPoint;
/*
* 切面类
**/
public class TargetAspect {/** 前置通知**/public void before() {System.out.println("conf前置通知");}public void after() {System.out.println("conf后置通知");}public void afterReturning() {System.out.println("conf后置返回通知");}public void afterThrowing(Exception ex) throws Exception {
// System.out.println("conf异常通知");
// System.out.println(ex.getMessage());}public Object around(ProceedingJoinPoint pjp) throws Throwable {Object proceed = null;if (!"".equals("admin")) {System.out.println("conf环绕前置");proceed = pjp.proceed(pjp.getArgs());System.out.println("conf环绕后置");}return proceed;}
}
3.3书写配置文件
<?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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id="target" class="com.heaboy.aopdemo.confaop.Target"/><bean id="targetAspect" class="com.heaboy.aopdemo.confaop.TargetAspect"/><!--proxy-target-class="true" 表示使用cglib代理.默认为false,创建有接口的jdk代理--><aop:config proxy-target-class="true"><!--切面:由切入点和通知组成--><aop:aspect ref="targetAspect"><!--切入点 pointcut--><aop:pointcut id="pointcut" expression="execution(* com.heaboy.aopdemo.confaop.*.*(..))"/><!--增强/通知 advice--><aop:before method="before" pointcut-ref="pointcut"/><aop:after method="after" pointcut-ref="pointcut"/><aop:around method="around" pointcut-ref="pointcut"/><aop:after-returning method="afterReturning" pointcut-ref="pointcut"/><aop:after-throwing method="afterThrowing" throwing="ex" pointcut-ref="pointcut"/></aop:aspect></aop:config>
</beans>
3.4启动测试
public class AopTest {public static void main(String[] args) {ApplicationContext appCtx = new ClassPathXmlApplicationContext("spring-confaop.xml");Target targetProxy = (Target) appCtx.getBean("target");System.out.println(targetProxy.method3(1));}
}
相关文章:
Spring AOP的几种实现方式
1.通过注解实现 1.1导入依赖 <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.1.6.RELEASE</version></dependency> 1.2定义注解 import java.lang.annotation.*;Targ…...
字节码编程bytebuddy之实现抽象类并并添加自定义注解
写在前面 本文看下使用bytebuddy如何实现抽象类,并在子类中添加自定义注解。 1:代码 1.1:准备基础代码 类和方法注解 package com.dahuyou.bytebuddy.cc.mine;import java.lang.annotation.ElementType; import java.lang.annotation.Re…...
LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结
文章目录 前言步骤图片数据Embedding入库文本检索 完整代码 前言 本文使用阿里云的向量检索服务(DashVector),结合 ONE-PEACE多模态模型,构建实时的“文本搜图片”的多模态检索能力。整体流程如下: 多模态数据Embedd…...
CentOS7安装部署git和gitlab
安装Git 在Linux系统中是需要编译源码的,首先下载所需要的依赖: yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker方法一 下载: wget https://mirrors.edge.kernel.org/pub/s…...
《昇思25天学习打卡营第16天|基于MindNLP+MusicGen生成自己的个性化音乐》
MindNLP 原理 MindNLP 是一个自然语言处理(NLP)框架,用于处理和分析文本数据。 文本预处理:包括去除噪声、分词、词性标注、命名实体识别等步骤,使文本数据格式化并准备好进行进一步分析。 特征提取:将文…...
算法学习day10(贪心算法)
贪心算法:由局部最优->全局最优 贪心算法一般分为如下四步: 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 一、摆动序列(理解难) 连续数字之间的差有正负的交替&…...
卡尔曼滤波Kalman Filter零基础入门到实践(上部)
参考视频:入门(秒懂滤波概要)_哔哩哔哩_bilibili 一、入门 1.引入 假设超声波距离传感器每1ms给单片机发数据。 理论数据为黑点, 测量数据曲线为红线,引入滤波后的数据为紫线 引入滤波的作用是过滤数据中的噪声&a…...
力扣-dfs
何为深度优先搜索算法? 深度优先搜索算法,即DFS。就是找一个点,往下搜索,搜索到尽头再折回,走下一个路口。 695.岛屿的最大面积 695. 岛屿的最大面积 题目 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相…...
keepalived高可用集群
一、keepalived: 1.keepalive是lvs集群中的高可用架构,只是针对调度器的高可用,基于vrrp来实现调度器的主和备,也就是高可用的HA架构;设置一台主调度器和一台备调度器,在主调度器正常工作的时候࿰…...
文献翻译与阅读《Integration Approaches for Heterogeneous Big Data: A Survey》
CYBERNETICS AND INFORMATION TECHNOLOGIES’24 论文原文下载地址:原文下载 目录 1 引言 2 大数据概述 3 大数据的异构性 4 讨论整合方法 4.1 大数据仓库(BDW) 4.2 大数据联盟(BDF) 5 DW 和 DF 方法的比较、分…...
应用最优化方法及MATLAB实现——第3章代码实现
一、概述 在阅读最优方法及MATLAB实现后,想着将书中提供的代码自己手敲一遍,来提高自己对书中内容理解程度,巩固一下。 这部分内容主要针对第3章的内容,将其所有代码实现均手敲一遍,中间部分代码自己根据其公式有些许的…...
django的增删改查,排序,分组等常用的ORM操作
Django 的 ORM(对象关系映射)提供了一种方便的方式来与数据库进行交互。 1. Django模型 在 myapp/models.py 中定义一个示例模型:python from django.db import modelsclass Person(models.Model):name models.CharField(max_length100)age…...
Leetcode Java学习记录——树、二叉树、二叉搜索树
文章目录 树的定义树的遍历中序遍历代码 二叉搜索树 常见二维数据结构:树/图 树和图的区别就在于有没有环。 树的定义 public class TreeNode{public int val;public TreeNode left,right;public TreeNode(int val){this.val val;this.left null;this.right nu…...
华为HCIP Datacom H12-821 卷30
1.单选题 以下关于OSPF协议报文说法错误的是? A、OSPF报文采用UDP报文封装并且端口号是89 B、OSPF所有报文的头部格式相同 C、OSPF协议使用五种报文完成路由信息的传递 D、OSPF所有报文头部都携带了Router-ID字段 正确答案:A 解析: OSPF用IP报文直接封装协议报文,…...
element el-table实现表格动态增加/删除/编辑表格行,带校验规则
本篇文章记录el-table增加一行可编辑的数据列,进行增删改。 1.增加空白行 直接在页面mounted时对form里面的table列表增加一行数据,直接使用push() 方法增加一列数据这个时候也可以设置一些默认值。比如案例里面的 产品件数 。 mounted() {this.$nextTi…...
QT调节屏幕亮度
1、目标 利用QT实现调节屏幕亮度功能:在无屏幕无触控时,将屏幕亮度调低,若有触控则调到最亮。 2、调节亮度命令 目标装置使用嵌入式Linux系统,调节屏幕亮度的指令为: echo x > /sys/class/backlight/backlight/…...
实变函数精解【3】
文章目录 点集求导集 闭集参考文献 点集 求导集 例1 E { 1 / n 1 / m : n , m ∈ N } 1. lim n → ∞ ( 1 / n 1 / m ) 1 / m 2. lim n , m → ∞ ( 1 / n 1 / m ) 0 3. E ′ { 0 , 1 , 1 / 2 , 1 / 3 , . . . . } E\{1/n1/m:n,m \in N\} \\1.\lim_{n \rightar…...
JVM:SpringBoot TomcatEmbeddedWebappClassLoader
文章目录 一、介绍二、SpringBoot中TomcatEmbeddedWebappClassLoader与LaunchedURLClassLoader的关系 一、介绍 TomcatEmbeddedWebappClassLoader 是 Spring Boot 在其内嵌 Tomcat 容器中使用的一个类加载器(ClassLoader)。在 Spring Boot 应用中&#…...
蜂窝互联网接入:连接世界的无缝体验
通过Wi—Fi,人们可以方便地接入互联网,但无线局域网的覆盖范围通常只有10~100m。当我们携带笔记本电脑在外面四处移动时,并不是在所有地方都能找到可接入互联网的Wi—Fi热点,这时候蜂窝移动通信系统可以为我们提供广域…...
Sprint Boot 2 核心功能(一)
核心功能 1、配置文件 application.properties 同基础入门篇的application.properties用法一样 Spring Boot 2 入门基础 application.yaml(或application.yml) 基本语法 key: value;kv之间有空格大小写敏感使用缩进表示层级关系缩进不允…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
