企业级信息系统开发——初探Spring AOP

news2024/12/29 8:59:41

文章目录

  • 一、提出游吟诗人唱赞歌任务
    • (一)采用传统方式实现
    • (二)采用传统方式实现的缺点
  • 二、采用配置方式使用AOP
    • (一)创建本讲所需子包
    • (二)创建杀龙任务类
    • (三)创建勇敢骑士类
    • (四)创建游吟诗人类
    • (五)创建Spring配置文件
    • (六)添加AOP相关依赖
    • (七)创建测试类 - TestKnight
    • (八)运行测试方法,查看结果
  • 三、采用注解方式使用AOP
    • (一)创建子包
    • (二)创建杀龙任务类
    • (三)创建勇敢骑士类
    • 创建游吟诗人切面
    • (五)创建Spring配置类
    • (六)创建骑士测试类
    • (七)测试勇敢骑士,查看效果
  • 四、实现注解式拦截
    • (一)创建注解接口
    • (二)修改勇敢骑士类
    • (三)修改游吟诗人切面
    • (四)测试勇敢骑士

一、提出游吟诗人唱赞歌任务

  • 骑士执行任务前和执行任务后,游吟诗人唱赞歌

(一)采用传统方式实现

  • 修改day04子包的勇敢骑士类
    在这里插入图片描述
  • 执行测试类 - TestKnight
    在这里插入图片描述

(二)采用传统方式实现的缺点

  • 每个骑士类的embarkOnQuest()方法都要修改,耦合度太高,当骑士类数量很大时,这个任务完成起来就十分枯燥繁琐。

二、采用配置方式使用AOP

(一)创建本讲所需子包

  • net.shuai.spring包里创建day05.aop_xml子包
    在这里插入图片描述

(二)创建杀龙任务类

  • aop_xml子包里创建杀龙任务类 - SlayDragonQuest
package net.shuai.spring.day05.aop_xml;


import org.springframework.stereotype.Component;

/**
 * 功能:杀龙任务类
 */
@Component
public class SlayDragonQuest {
    public void embark() {
        System.out.println("执行杀龙任务……");
    }
}

(三)创建勇敢骑士类

  • aop_xml子包里创建勇敢骑士类 - BraveKnight
package net.shuai.spring.day05.aop_xml;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 功能:勇敢骑士类
 */
@Component("RobinHood")
public class BraveKnight {
    @Value("罗宾汉")
    private String name;
    @Autowired
    private SlayDragonQuest slayDragonQuest;

    public void embarkOnQuest() {
        System.out.print("勇敢骑士[" + name + "]");
        slayDragonQuest.embark();
    }
}

(四)创建游吟诗人类

  • aop_xml子包里创建游吟诗人类 - Minstrel
package net.shuai.spring.day05.aop_xml;

import org.springframework.stereotype.Component;

/**
 * 功能:游吟诗人类
 */
@Component
public class Minstrel {
    /**
     * 骑士出发前唱赞歌
     */
    public void singBeforeQuest() {
        System.out.println("啦啦啦,骑士出发了~");
    }

    /**
     * 骑士凯旋时唱赞歌
     */
    public void singAfterQuest() {
        System.out.println("真棒啊!骑士完成了任务~");
    }
}

(五)创建Spring配置文件

  • resources里创建aop_xml目录,在里面创建spring-config.xml配置文件
<?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:context="http://www.springframework.org/schema/context"
       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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--组件扫描-->
    <context:component-scan base-package="net.shuai.spring.day05.aop_xml"/>

    <!--配置AOP-->
    <aop:config>
        <!--定义切面-->
        <aop:aspect ref="minstrel">
            <!--定义切点-->
            <aop:pointcut id="embark" expression="execution(* net.shuai.spring.day05..*.embarkOnQuest(..))"/>
            <!--声明前置通知-->
            <aop:before method="singBeforeQuest" pointcut-ref="embark"/>
            <!--声明后置通知-->
            <aop:after method="singAfterQuest" pointcut-ref="embark"/>
        </aop:aspect>
    </aop:config>
</beans>

(六)添加AOP相关依赖

  • 在pom.xml文件里添加AOP相关依赖
<!--Spring AOP-->                                         
<dependency>                                              
    <groupId>org.springframework</groupId>                
    <artifactId>spring-aop</artifactId>                   
    <version>5.3.25</version>                  
</dependency>                                             
<!--AspectJ支持-->                                          
<dependency>                                              
    <groupId>aspectj</groupId>                            
    <artifactId>aspectjrt</artifactId>                    
    <version>1.5.4</version>                              
</dependency>                                             
<dependency>                                              
    <groupId>org.aspectj</groupId>                        
    <artifactId>aspectjweaver</artifactId>                
    <version>1.9.19</version>                              
    <scope>runtime</scope>                                
</dependency>                                             

(七)创建测试类 - TestKnight

  • test/java里创建net.shuai.spring.day05.aop_xml包,在包里创建TestKnight`类
package net.shuai.spring.day05.aop_xml;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 功能:测试骑士类
 */
public class TestKnight {
    private ClassPathXmlApplicationContext context; // 基于类路径XML配置文件的应用容器

    @Before
    public void init() {
        // 基于Spring配置文件创建应用容器
        context = new ClassPathXmlApplicationContext("aop_xml/spring-config.xml");
    }

    @Test
    public void testBraveKnight() {
        // 根据名称从应用容器里获取勇敢骑士对象
        BraveKnight braveKnight = (BraveKnight) context.getBean("RobinHood");
        // 勇敢骑士执行任务
        braveKnight.embarkOnQuest();
    }

    @After
    public void destroy() {
        // 关闭应用容器
        context.close();
    }
}

(八)运行测试方法,查看结果

  • 运行testBraveKinght()方法
    在这里插入图片描述

三、采用注解方式使用AOP

(一)创建子包

  • net.shuai.spring包里创建day05.aop_annotation子包
    在这里插入图片描述

(二)创建杀龙任务类

  • aop_annotation子包里创建杀龙任务类 - SlayDragonQuest
package net.shuai.spring.day05.aop_annotation;

import org.springframework.stereotype.Component;

/**
 * 功能:杀龙任务类
 */
@Component
public class SlayDragonQuest {
    public void embark() {
        System.out.println("执行杀龙任务……");
    }
}

(三)创建勇敢骑士类

  • aop_annotation子包里创建勇敢骑士类 - BraveKnight
package net.shuai.spring.day05.aop_annotation;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 功能:勇敢骑士类
 */
@Component("RobinHood")
public class BraveKnight {
    @Value("罗宾汉")
    private String name;
    @Autowired
    private SlayDragonQuest slayDragonQuest;

    /**
     * 勇敢骑士执行杀龙任务
     */
    public void embarkOnQuest() {
        System.out.print("勇敢骑士[" + name + "]");
        slayDragonQuest.embark();
    }
}

创建游吟诗人切面

  • aop_annotation子包里创建游吟诗人切面 - MinstrelAspect
package net.shuai.spring.day05.aop_annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * 功能:游吟诗人切面类
 */
@Aspect // 声明为切面类
@Component("minstrel") // 声明为Spring组件
public class MinstrelAspect {
    // 注解声明切入点
    @Pointcut("execution(* net.shuai.spring.day05..*.embarkOnQuest(..))")
    public void embark() {
    }

    // 注解声明前置通知
    @Before("embark()")
    public void singBeforeQuest(JoinPoint joinPoint) {
        System.out.println("啦啦啦,骑士出发了~");
    }

    // 注解声明后置通知
    @After("embark()")
    public void singAfterQuest(JoinPoint joinPoint) {
        System.out.println("真棒啊!骑士完成了任务~");
    }
}

(五)创建Spring配置类

  • aop_annotation子包里创建Spring配置类 - SpringConfig
package net.shuai.spring.day05.aop_annotation;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * 功能:Spring配置类
 */
@Configuration // 声明为Spring配置类
@ComponentScan("net.shuai.spring.day05.aop_annotation") // 组件扫描
@EnableAspectJAutoProxy // 启用Spring对AspectJ的支持
public class SpringConfig {
}

(六)创建骑士测试类

  • test/java/的aop_annotation子包里创建测试类 - TestKnight
package net.shuai.spring.day05.aop_annotation;


import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * 功能:测试骑士类
 */
public class TestKnight {
    private AnnotationConfigApplicationContext context; // 基于注解配置类的应用容器

    @Before
    public void init() {
        // 基于注解配置类创建应用容器
        context = new AnnotationConfigApplicationContext(SpringConfig.class);
    }

    @Test
    public void testBraveKnight() {
        // 根据名称从应用容器里获取勇敢骑士对象
        BraveKnight knight = (BraveKnight) context.getBean("RobinHood");
        // 勇敢骑士执行任务
        knight.embarkOnQuest();
    }

    @After
    public void destroy() {
        // 关闭应用容器
        context.close();
    }
}

(七)测试勇敢骑士,查看效果

  • 运行测试方法 - testBraveKnight()
    在这里插入图片描述

四、实现注解式拦截

(一)创建注解接口

  • aop_annotation子包里创建注解接口 - Action (名字可以任取)
package net.shuai.spring.day05.aop_annotation;
import java.lang.annotation.*;

/**
 * 功能:动作注解接口
 */
@Target(ElementType.METHOD) // 声明拦截目标 - 方法
@Retention(RetentionPolicy.RUNTIME) // 保留策略 - 运行时
@Documented // 注解文档化
public @interface Action {
    String name();
}

(二)修改勇敢骑士类

  • embarkOnQuest()添加自定义注解Action,并设置其name属性
    在这里插入图片描述

(三)修改游吟诗人切面

package net.shuai.spring.day05.aop_annotation;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 功能:游吟诗人切面类
 */
@Aspect // 声明为切面类
@Component("minstrel") // 声明为Spring组件
public class MinstrelAspect {
    // 注解声明切入点
    @Pointcut("@annotation(net.shuai.spring.day05.aop_annotation.Action)")
    public void embark() {
    }

    // 注解声明前置通知
    @Before("embark()")
    public void singBeforeQuest(JoinPoint joinPoint) {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取被拦截的方法
        Method method = signature.getMethod();
        // 获取注解式拦截
        Action action = method.getAnnotation(Action.class);
        // 提示用户被拦截了
        System.out.println("[" + action.name() + "]拦截了[" + method.getName() + "]:拦截前~");

        System.out.println("啦啦啦,骑士出发了~");
    }

    // 注解声明后置通知
    @After("embark()")
    public void singAfterQuest(JoinPoint joinPoint) {
        // 获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        // 获取被拦截的方法
        Method method = signature.getMethod();
        // 获取注解式拦截
        Action action = method.getAnnotation(Action.class);
        // 提示用户被拦截了
        System.out.println("[" + action.name() + "]拦截了[" + method.getName() + "]:拦截后~");

        System.out.println("真棒啊!骑士完成了任务~");
    }
}

(四)测试勇敢骑士

  • 运行测试方法testBraveKnight(),查看效果
    在这里插入图片描述

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

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

相关文章

VESD静电监控系统:提高静电防护效果与管理效率

随着科学技术不断发展&#xff0c;现代的工业对静电防护的要求越来越高。因为静电的存在可能会对产品质量、工作环境、甚至是人身产生威胁。静电监控系统是一项高效的管理工具&#xff0c;能够有效地控制和监测静电产生的情况&#xff0c;提高静电防护效果和管理效率。 VESD静电…

群晖DS920 video station使用教程

群晖DS920 video station使用教程 为了更好的浏览体验&#xff0c;欢迎光顾勤奋的凯尔森同学个人博客http://www.huerpu.cc:7000 安装video station在群晖套件里点一下就好&#xff0c;这里不说了。 一、添加视频库 可以添加电视剧、电视节目等类型。 比如我在国产剧这个视频…

写出诗一样代码的灵丹妙药: const与assert

&#x1f929;本文作者&#xff1a;大家好&#xff0c;我是paperjie&#xff0c;感谢你阅读本文&#xff0c;欢迎一建三连哦。 &#x1f970;内容专栏&#xff1a;这里是《C知识系统分享》专栏&#xff0c;笔者用重金(时间和精力)打造&#xff0c;基础知识一网打尽&#xff0c;…

网络安全好就业吗?会不会容易被淘汰?

网络安全发展前景好吗&#xff1f;好就业吗&#xff1f;会不会容易被淘汰&#xff1f;很多刚入门或者想入门的小伙伴都会有这样的疑问 今天就在这里给大家介绍一下。我就在这个行业&#xff0c;目前湖南&#xff0c;薪资就没必要说了&#xff0c;高就对了。 这个行业优势就是工…

互联网营销推荐算法理论-30分钟理解协同过滤

一、协同过滤概念 不论在淘宝还是京东&#xff0c;你浏览了/购买了某个商品A&#xff0c;后面几天你在该app内总是会在首页看到商品A和商品A相似的商品&#xff0c;背后支撑这种能力的就是推荐系统&#xff0c;而其推荐算法可能就是协同过滤。&#xff08;注&#xff1a;app内…

Scala学习(九)---List集合

文章目录 1.List1.1 不可变List集合1.2 可变集合ListBuffer 1.List List集合默认为不可变集合&#xff0c;List集合在实例化的时候&#xff0c;无法通过new关键字进行实例化&#xff0c;只能通过伴生apply方法来对其进行实例化 1.1 不可变List集合 创建一个不可变list集合 …

真题详解(树的结点)-软件设计(八十四)

真题详解&#xff08;汇总&#xff09;-软件设计&#xff08;八十三)https://blog.csdn.net/ke1ying/article/details/130856130?spm1001.2014.3001.5501 COCOMOII估算不包括_____。 对象点 B.功能点 C.用例数 D.源代码行 答案&#xff1a;C 语法翻译是一种&#xff…

【vue3】 实现 公共搜索组件,在当前页搜索的路由跳转不能改变当前值的操作,使用bus / event-emitter 派发器

一、安装 bus 插件 cnpm install --save event-emitter 二、创建 bus.ts 文件 1、在utils下创建bus.ts 2、bus.ts 代码如下 import ee from event-emitter export default ee() 三、页面使用 1、搜索的公用组件页面&#xff0c;search.vue <el-input v-model.trim&qu…

全网最详细实现微信小程序小程序支付功能【前端部分】

文章目录 功能描述&#xff1a;准备工作申请微信支付接口权限 微信支付api需要的参数说明示例代码 需要传入后端接口的参数说明&#xff1a;接口返回的参数说明&#xff1a;支付逻辑代码&#xff08;只包含支付功能&#xff09;以下是功能完整代码确认订单页面结构部分逻辑部分…

【阿里云】文本转语音方言— 阿里云语音合成,文本转语音方言工具类

目录 一、导入SDK坐标 二、文本转语音方言 —步骤和工具类 1.登录阿里云账号&#xff0c;创建一个语音合成项目和创建用户并设置权限。 2.获取appKey、accessKeyId、accessKeySecret在相应位置进行填写。 3.相应位置填写自己需要保存的本地路径。意思就是说&#xff0c;自…

【HarmonyOS】低代码元服务开发中的地图实现

在元服务开发过程中&#xff0c;大家可能需要在应用中使用地图&#xff0c;如果使用SDK集成的方式&#xff0c;地图SDK包体积大小很大&#xff0c;集成后元服务大小可能会超过10M&#xff0c;这就超出了HAP包的大小限制。那么是否有其他途径可以在元服务中使用地图呢&#xff1…

视频理解学习笔记(一):双流卷积神经网络

视频理解学习笔记&#xff08;一&#xff09;&#xff1a;双流卷积神经网络 两句话总结双流卷积神经网络论文概览方法详解Spatial stream ConvNetTemporal stream ConvNet测试方法 光流什么是光流怎么预处理光流 数据集UCF101&#xff08;已被刷爆&#xff09;HMDB51 Experimen…

安装包UI美化之路-Electron打包出界面美观,功能完善的安装包,这三步就够了

这篇文章应该说是《安装包UI美化之路-nsNiuniuSkin安装包制作可视化配置向导》的延伸与进一步应用&#xff0c;在可视配置的基础之上&#xff0c;生成供electron-builder打包的脚本&#xff01; 一直有朋友反馈&#xff0c;不知道如何将nsNiuniuSkin与Electron打包结合起来&am…

Real-Time C++ 嵌入式C++ 程序设计(二)

翻译自 Real-Time C Efficient Object-Oriented and Template Microcontroller Programming 4th Edition - Kormanyos, Christopher&#xff0c;这书涉及了从C11 到C20 的内容&#xff0c;主要介绍使用C 的模板、面向对象等特性设计嵌入式程序。书里的示例代码都是公开的&#…

【OpenCV DNN】Flask 视频监控目标检测教程 03

欢迎关注『OpenCV DNN Youcans』系列&#xff0c;持续更新中 【OpenCV DNN】Flask 视频监控目标检测教程 03 3.3 上传本地图片进行人脸检测3.3.1 OpenCV 级联分类器类 cv::CascadeClassifier3.3.2 cvFlask03 项目的构建步骤 本系列从零开始&#xff0c;详细讲解使用 Flask 框架…

Unity3D :运行时 UI 的性能注意事项

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 运行时 UI 的性能注意事项 本页介绍如何提高运行时的性能用户界面 . 优化数据存储 您可以使用 usageHints 来设置元素在运行时的使用方式&#xff0c;以便相应地优化数据存储。例…

三、CNNs网络架构-跨层连接思想的网络架构

《A review of convolutional neural network architectures and their optimizations》论文指出随着网络架构的深入&#xff0c;梯度消失、爆炸或退化问题变得越来越严重。跨层连接的思想是解决现有问题的有效方案&#xff0c;允许网络在非相邻层之间传递信息。因此&#xff0…

如何利用Python中的pymysql库来操作Mysql数据库,看这篇就够啦~

为了使python连接上数据库&#xff0c;你需要一个驱动&#xff0c;这个驱动是用于与数据库交互的库&#xff0c;本文是向大家介绍了如何利用python中的pymysql库来操作mysql数据库。 1、什么是pymysql&#xff1f; pymysql是从python连接到mysql数据库服务器的接口&#xff0c…

上门服务小程序|东邻到家系统|上门服务系统包含哪些功能?

使用东郊到家小程序&#xff0c;只需要一键预约即可在工作之余、休息娱乐的时候&#xff0c;点一个理按疗摩技师&#xff0c;做一个SPA&#xff0c;缓解工作压力&#xff0c;不失为一种享受&#xff0c;并且上门服务小程序可以为技师或从业岗位人员提供就业服务&#xff0c;线上…

抖音seo优化源代码搭建+抖音小程序私有化开源部署

抖音seo优化源码&#xff0c;抖音seo矩阵系统搭建&#xff0c;抖音账号矩阵系统开发&#xff0c;企业在做账号矩阵过程中&#xff0c;最头疼的莫过于私域线索转化&#xff0c;作为开发者都知道&#xff0c;目前市面上我们了解的矩阵系统除了挂载POI信息外&#xff0c;无法挂载留…