当前位置: 首页 > news >正文

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如何实现抽象类&#xff0c;并在子类中添加自定义注解。 1&#xff1a;代码 1.1&#xff1a;准备基础代码 类和方法注解 package com.dahuyou.bytebuddy.cc.mine;import java.lang.annotation.ElementType; import java.lang.annotation.Re…...

LLM-阿里云 DashVector + ModelScope 多模态向量化实时文本搜图实战总结

文章目录 前言步骤图片数据Embedding入库文本检索 完整代码 前言 本文使用阿里云的向量检索服务&#xff08;DashVector&#xff09;&#xff0c;结合 ONE-PEACE多模态模型&#xff0c;构建实时的“文本搜图片”的多模态检索能力。整体流程如下&#xff1a; 多模态数据Embedd…...

CentOS7安装部署git和gitlab

安装Git 在Linux系统中是需要编译源码的&#xff0c;首先下载所需要的依赖&#xff1a; yum install -y curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker方法一 下载&#xff1a; wget https://mirrors.edge.kernel.org/pub/s…...

《昇思25天学习打卡营第16天|基于MindNLP+MusicGen生成自己的个性化音乐》

MindNLP 原理 MindNLP 是一个自然语言处理&#xff08;NLP&#xff09;框架&#xff0c;用于处理和分析文本数据。 文本预处理&#xff1a;包括去除噪声、分词、词性标注、命名实体识别等步骤&#xff0c;使文本数据格式化并准备好进行进一步分析。 特征提取&#xff1a;将文…...

算法学习day10(贪心算法)

贪心算法&#xff1a;由局部最优->全局最优 贪心算法一般分为如下四步&#xff1a; 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 一、摆动序列&#xff08;理解难&#xff09; 连续数字之间的差有正负的交替&…...

卡尔曼滤波Kalman Filter零基础入门到实践(上部)

参考视频&#xff1a;入门&#xff08;秒懂滤波概要&#xff09;_哔哩哔哩_bilibili 一、入门 1.引入 假设超声波距离传感器每1ms给单片机发数据。 理论数据为黑点&#xff0c; 测量数据曲线为红线&#xff0c;引入滤波后的数据为紫线 引入滤波的作用是过滤数据中的噪声&a…...

力扣-dfs

何为深度优先搜索算法&#xff1f; 深度优先搜索算法&#xff0c;即DFS。就是找一个点&#xff0c;往下搜索&#xff0c;搜索到尽头再折回&#xff0c;走下一个路口。 695.岛屿的最大面积 695. 岛屿的最大面积 题目 给你一个大小为 m x n 的二进制矩阵 grid 。 岛屿 是由一些相…...

keepalived高可用集群

一、keepalived&#xff1a; 1.keepalive是lvs集群中的高可用架构&#xff0c;只是针对调度器的高可用&#xff0c;基于vrrp来实现调度器的主和备&#xff0c;也就是高可用的HA架构&#xff1b;设置一台主调度器和一台备调度器&#xff0c;在主调度器正常工作的时候&#xff0…...

文献翻译与阅读《Integration Approaches for Heterogeneous Big Data: A Survey》

CYBERNETICS AND INFORMATION TECHNOLOGIES’24 论文原文下载地址&#xff1a;原文下载 目录 1 引言 2 大数据概述 3 大数据的异构性 4 讨论整合方法 4.1 大数据仓库&#xff08;BDW&#xff09; 4.2 大数据联盟&#xff08;BDF&#xff09; 5 DW 和 DF 方法的比较、分…...

应用最优化方法及MATLAB实现——第3章代码实现

一、概述 在阅读最优方法及MATLAB实现后&#xff0c;想着将书中提供的代码自己手敲一遍&#xff0c;来提高自己对书中内容理解程度&#xff0c;巩固一下。 这部分内容主要针对第3章的内容&#xff0c;将其所有代码实现均手敲一遍&#xff0c;中间部分代码自己根据其公式有些许的…...

django的增删改查,排序,分组等常用的ORM操作

Django 的 ORM&#xff08;对象关系映射&#xff09;提供了一种方便的方式来与数据库进行交互。 1. Django模型 在 myapp/models.py 中定义一个示例模型&#xff1a;python from django.db import modelsclass Person(models.Model):name models.CharField(max_length100)age…...

Leetcode Java学习记录——树、二叉树、二叉搜索树

文章目录 树的定义树的遍历中序遍历代码 二叉搜索树 常见二维数据结构&#xff1a;树/图 树和图的区别就在于有没有环。 树的定义 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增加一行可编辑的数据列&#xff0c;进行增删改。 1.增加空白行 直接在页面mounted时对form里面的table列表增加一行数据&#xff0c;直接使用push() 方法增加一列数据这个时候也可以设置一些默认值。比如案例里面的 产品件数 。 mounted() {this.$nextTi…...

QT调节屏幕亮度

1、目标 利用QT实现调节屏幕亮度功能&#xff1a;在无屏幕无触控时&#xff0c;将屏幕亮度调低&#xff0c;若有触控则调到最亮。 2、调节亮度命令 目标装置使用嵌入式Linux系统&#xff0c;调节屏幕亮度的指令为&#xff1a; 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 容器中使用的一个类加载器&#xff08;ClassLoader&#xff09;。在 Spring Boot 应用中&#…...

蜂窝互联网接入:连接世界的无缝体验

通过Wi—Fi&#xff0c;人们可以方便地接入互联网&#xff0c;但无线局域网的覆盖范围通常只有10&#xff5e;100m。当我们携带笔记本电脑在外面四处移动时&#xff0c;并不是在所有地方都能找到可接入互联网的Wi—Fi热点&#xff0c;这时候蜂窝移动通信系统可以为我们提供广域…...

Sprint Boot 2 核心功能(一)

核心功能 1、配置文件 application.properties 同基础入门篇的application.properties用法一样 Spring Boot 2 入门基础 application.yaml&#xff08;或application.yml&#xff09; 基本语法 key: value&#xff1b;kv之间有空格大小写敏感使用缩进表示层级关系缩进不允…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八

现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet&#xff0c;点击确认后如下提示 最终上报fail 解决方法 内核升级导致&#xff0c;需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...