利用Spring AOP与Python装饰器完成相同任务

news2024/11/17 23:57:25

文章目录

  • 一、提出任务
  • 二、采用配置方式Spring AOP完成任务
    • 1. 项目结构
    • 2. 创建任务类
      • SlayDragonQuest.java
      • RescueDamselQuest.java
    • 3. 创建骑士类
      • BraveKnight.java
      • RescueDamselKnight.java
    • 4. 创建游吟诗人类
      • Minstrel.java
    • 5. 创建Spring配置文件
      • spring-config.xml
    • 6. 添加AOP相关依赖
    • 7. 创建测试类
      • TestKnight.java
    • 8. 运行测试方法
  • 三、利用Python装饰器完成任务
    • 1. 创建程序,实现功能
    • 2. 运行程序,查看结果
  • 四、实战小结

一、提出任务

  • 骑士执行任务前和执行任务后,游吟诗人唱赞歌
    在这里插入图片描述

二、采用配置方式Spring AOP完成任务

在这里插入图片描述

1. 项目结构

src/main/java
│
└── net
    └── huawei
        └── spring
            └── day05
                └── aop_xml
                    ├── BraveKnight.java
                    ├── Minstrel.java
                    ├── RescueDamselKnight.java
                    ├── RescueDamselQuest.java
                    └── SlayDragonQuest.java

src/main/resources
│
└── aop_xml
    └── spring-config.xml

src/test/java
│
└── net
    └── huawei
        └── spring
            └── day05
                └── aop_xml
                    └── TestKnight.java

2. 创建任务类

SlayDragonQuest.java

package net.huawei.spring.day05.aop_xml;

import org.springframework.stereotype.Component;

/**
 * 功能:创建杀龙任务类
 * 作者:华卫
 * 日期:2024年04月22日
 */
@Component
public class SlayDragonQuest {
    public void embark() {
        System.out.println("执行杀龙任务……");
    }
}

RescueDamselQuest.java

package net.huawei.spring.day05.aop_xml;

import org.springframework.stereotype.Component;

/**
 * 功能:救美任务类
 * 作者:华卫
 * 日期:2024年04月22日
 */
@Component
public class RescueDamselQuest {
    public void embark() {
        System.out.println("执行救美任务……");
    }
}

3. 创建骑士类

BraveKnight.java

package net.huawei.spring.day05.aop_xml;

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

/**
 * 功能:勇敢骑士类
 * 作者:华卫
 * 日期:2024年04月22日
 */
@Component
public class BraveKnight {
    @Value("罗宾汉")
    private String name;
    @Autowired
    private SlayDragonQuest slayDragonQuest;

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

RescueDamselKnight.java

package net.huawei.spring.day05.aop_xml;

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

/**
 * 功能:救美骑士类
 * 作者:华卫
 * 日期:2024年04月22日
 */
@Component
public class RescueDamselKnight {
    @Value("格拉海德")
    private String name;
    @Autowired
    private RescueDamselQuest rescueDamselQuest;

    public void embarkOnQuest() {
        System.out.print("救美骑士[" + name + "]");
        rescueDamselQuest.embark();
    }
}

4. 创建游吟诗人类

Minstrel.java

package net.huawei.spring.day05.aop_xml;

import org.springframework.stereotype.Component;

/**
 * 功能:游吟诗人类
 * 作者:华卫
 * 日期:2024年04月22日
 */
@Component
public class Minstrel {
    public void singBeforeQuest() {
        System.out.println("啦啦啦,骑士出发了~");
    }

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

5. 创建Spring配置文件

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.huawei.spring.day05.aop_xml"/>

    <!-- 配置AOP -->
    <aop:config>
        <aop:aspect ref="minstrel">
            <aop:pointcut id="embark" expression="execution(* net.huawei.spring.day05..*.embarkOnQuest(..))"/>
            <aop:before method="singBeforeQuest" pointcut-ref="embark"/>
            <aop:after method="singAfterQuest" pointcut-ref="embark"/>
        </aop:aspect>
    </aop:config>
</beans>

6. 添加AOP相关依赖

pom.xml 中添加以下依赖:

<!--Spring AOP-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>6.1.5</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>

7. 创建测试类

TestKnight.java

package net.huawei.spring.day05.aop_xml;

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

/**
 * 功能:测试骑士类
 * 作者:华卫
 * 日期:2024年04月24日
 */
public class TestKnight {
    private ClassPathXmlApplicationContext context;

    @Before
    public void init() {
        context = new ClassPathXmlApplicationContext("aop_xml/spring-config.xml");
    }

    @Test
    public void testKnight() {
        BraveKnight knight1 = (BraveKnight) context.getBean("braveKnight");
        knight1.embarkOnQuest();
        RescueDamselKnight knight2 = (RescueDamselKnight) context.getBean("rescueDamselKnight");
        knight2.embarkOnQuest();
    }

    @After
    public void destroy() {
        context.close();
    }
}

8. 运行测试方法

运行 testKnight() 方法,验证结果是否符合预期

啦啦啦,骑士出发了~
勇敢骑士[罗宾汉]执行杀龙任务……
真棒啊!骑士完成了任务~
啦啦啦,骑士出发了~
救美骑士[格拉海德]执行救美任务……
真棒啊!骑士完成了任务~

通过以上步骤,成功使用Spring AOP配置了骑士任务,实现了任务前后唱赞歌的功能。

三、利用Python装饰器完成任务

1. 创建程序,实现功能

  • 创建Python程序 - 骑士完成任务.py
    在这里插入图片描述
# -*- coding: utf-8 -*-
"""
功能:骑士完成任务
作者:华卫
日期:2024年5月16日
"""

def minstrel(func):
    def wrapper(*args):
        print('啦啦啦,骑士出发了~')
        func(*args)
        print('真棒啊!骑士完成了任务~')        
    return wrapper

# 杀龙任务类
class SlayDragonQuest:
    def embark(self):
        print("执行杀龙任务……")

# 救美任务类
class RescueDamselQuest:
    def embark(self):
        print("执行救美任务……")

# 勇敢骑士类
class BraveKnight:
    def __init__(self, name=None, slay_dragon_quest=None):
        self._name = name
        self._slay_dragon_quest = slay_dragon_quest

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        self._name = name

    @property
    def slay_dragon_quest(self):
        return self._slay_dragon_quest

    @slay_dragon_quest.setter
    def slay_dragon_quest(self, slay_dragon_quest):
        self._slay_dragon_quest = slay_dragon_quest

    @minstrel
    def embark_on_quest(self):
        print(f"勇敢骑士[{self._name}]", end='')
        if self._slay_dragon_quest:
            self._slay_dragon_quest.embark()
        else:
            print("没有任务可以执行")

# 救美骑士类
class RescueDamselKnight:
    def __init__(self, name, rescue_damsel_quest):
        self._name = name
        self._rescue_damsel_quest = rescue_damsel_quest

    @property
    def name(self):
        return self._name

    @property
    def rescue_damsel_quest(self):
        return self._rescue_damsel_quest

    @minstrel
    def embark_on_quest(self):
        print(f"救美骑士[{self._name}]", end='')
        self._rescue_damsel_quest.embark()

if __name__ == '__main__':
    quest1 = SlayDragonQuest()
    knight1 = BraveKnight(name="罗宾汉", slay_dragon_quest=quest1)
    knight1.embark_on_quest()
    
    quest2 = RescueDamselQuest()
    knight2 = RescueDamselKnight(name="格拉海德", rescue_damsel_quest=quest2)
    knight2.embark_on_quest()

2. 运行程序,查看结果

  • 运行Python程序 - 骑士完成任务.py
    在这里插入图片描述

四、实战小结

  • 通过本次实战,我们成功使用Spring AOP和Python装饰器实现了骑士执行任务前后由游吟诗人唱赞歌的功能。使用Spring AOP,借助于AspectJ,我们能够在不修改业务逻辑代码的情况下,通过配置实现方法的前后增强。在Python中,通过装饰器简洁明了地实现了同样的功能,展现了Python装饰器在简化代码和增强功能方面的强大能力。两种方式都提高了代码的可读性和可维护性,达到了良好的解耦效果。

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

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

相关文章

MySQL的备份及恢复

目录 5、MySQL的备份及恢复 5.1 MySQL日志管理 5.1.1 MySQL日志类型 5.1.2 错误日志 5.1.3 通用查询日志 5.1.4 慢查询日志 5.1.5 二进制日志 开启日志 二进制日志管理>又叫日志滚动 二进制日志还原数据 删除二进制日志文件&#xff1a; 5.1.6实例&#xff1a; 使用mysqlbi…

wordpress教程视频 wordpress教程网盘 wordpress教程推荐wordpress教程网

WordPress&#xff0c;作为一款强大且灵活的开源内容管理系统&#xff0c;已成为许多网站开发者与运营者的首选。其强大的功能、丰富的插件以及易于上手的特点&#xff0c;使得无论是初学者还是专业开发者都能轻松构建出个性化的网站。然而&#xff0c;对于初学者来说&#xff…

【LeetCode算法】第69题:x的平方根

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路&#xff1a;第一次想到的是让i从1开始遍历&#xff0c;看i*ix是否成立&#xff0c;但是这样就会导致i*i超出了int的范围&#xff0c;无法正常求解。第二次&#xff0c;想着比较x/…

Design-expert中的ANOVA分析

文章目录 1.ANOVA for Quadratic model部分2.Fit Statistics部分3.拟合方程含义 1.ANOVA for Quadratic model部分 在Design-Expert软件中&#xff0c;ANOVA&#xff08;Analysis of Variance&#xff09;用于评估模型中各个参数的显著性&#xff0c;特别是在处理二次模型&…

流媒体新篇章:Nginx-RTMP Docker部署全攻略

概述 Nginx-RTMP-Docker是一种基于Docker的Nginx流媒体服务器解决方案。具体来说&#xff0c;Nginx是一款高性能的Web和反向代理服务器&#xff0c;RTMP&#xff08;Real-Time Messaging Protocol&#xff09;是用于音频、视频数据传输的协议。Nginx-RTMP模块是由Alibaba的李广…

Redis离线安装(单机)

目录 1-环境准备1-1下载redis-4.0.11.tar.gz1-2gcc环境 2-上传解压3-编译安装(需要gcc环境)4-配置redis5-启动Redis6-开启防火墙(root)7-添加开机启动脚本8-设置权限9-设置开机启动10-测试redis服务11-检查是否安装成功12-创建redis命令软连接13-测试redis14-必要时设置防火墙 …

浅析declval关键字

浅析 declval 关键字 文章目录 浅析 declval 关键字前言declval 的基本概念declval 的工作原理declval 的实际应用案例总结 前言 ​ 在现代C编程中&#xff0c;std::declval是一个非常有用的工具&#xff0c;它允许我们在不实例化对象的情况下使用其类型。这在模板元编程中尤其…

OpenAI 与 Reddit 达成重要合作伙伴关系

Reddit是一个娱乐、社交及新闻网站&#xff0c;注册用户可以将文字或链接在网站上发布&#xff0c;使它基本上成为了一个电子布告栏系统。注册用户可以对这些帖子进行投票&#xff0c;结果将被用来进行排名和决定它在首页或子页的位置。网站上的内容分类被称为“subreddit”。s…

Vue3实战笔记(39)—封装页脚组件,附源码

文章目录 前言一、封装页脚组件二、使用组件总结 前言 在Web开发中&#xff0c;页脚组件是一个重要的部分&#xff0c;它为用户提供关于网站的信息、导航链接以及版权声明等。而封装页脚组件则是一种高效的方法&#xff0c;可以提高代码的可重用性和可维护性。 一、封装页脚组…

4.2 循环语句(for, while)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

高中数学:平面向量-正交分解、坐标表示、坐标运算

一、正交分解 二、坐标表示 这里注意一点 坐标A(x,y)与向量 a → \mathop{a}\limits ^{\rightarrow} a→的坐标记作&#xff1a; a → \mathop{a}\limits ^{\rightarrow} a→(x,y)&#xff0c;表示方式的区别 引申 三、加减运算的坐标表示 四、数乘运算的坐标表示 引申 两向量…

爬虫学习--12.MySQL数据库的基本操作(下)

MySQL查询数据 MySQL 数据库使用SQL SELECT语句来查询数据。 语法&#xff1a;在MySQL数据库中查询数据通用的 SELECT 语法 SELECT 字段1&#xff0c;字段2&#xff0c;……&#xff0c;字段n FROM table_name [WHERE 条件] [LIMIT N] 查询语句中你可以使用一个或者多个表&…

golang创建式设计模式---工厂模式

创建式设计模式—工厂模式 目录导航 创建式设计模式---工厂模式1)什么是工厂模式2)使用场景3)实现方式4)实践案例5)优缺点分析 1)什么是工厂模式 工厂模式(Factory Method Pattern)是一种设计模式&#xff0c;旨在创建对象时&#xff0c;将对象的创建与使用进行分离。通过定义…

GPIO模拟IIC通信测量环境光

目录 iic.h iic.c ap3216c.h ap3216.c main.c 实验效果 iic.h #ifndef __IIC_H__ #define __IIC_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h" //SDA 数据线为PF15 //SCL 时钟线为PF14//配置PF15为输出模式 #define SET_SDA_OUT d…

六.逼格拉满-Prometheus+Grafana微服务监控告警

前言 微服务架构是一个分布式系统&#xff0c;由多个独立的服务组成&#xff0c;每个服务可能运行在不同的容器、虚拟机或物理机上&#xff0c;那么在生产环境中我们需要随时监控服务的状态&#xff0c;以应对各种突发情况&#xff0c;比如&#xff1a;内存爆满&#xff0c;CP…

个人如何利用AI大模型工具搞钱

人工智能&#xff08;AI&#xff09;技术的迅速发展&#xff0c;使得许多以前难以想象的应用场景变得可能。尤其是AI大模型&#xff08;如GPT-4&#xff09;在自然语言处理、图像识别等方面表现出色&#xff0c;为个人带来了许多新的赚钱机会。本文将详细介绍几种个人如何利用A…

无接口文档快速模拟接口请求-postman 3步搞定;

一&#xff1a;接口&#xff1a;鼠标右键复制&#xff1a;以curl&#xff08;bash&#xff09;格式复制&#xff1a; 二&#xff1a;然后拷贝到postman黏贴的方式&#xff1a; 打开 postman &#xff0c; 点击左上角的 Import &#xff0c; 选择 Raw Text &#xff0c;黏贴后…

计算机毕业设计 | springboot+vue汽车修理管理系统 汽修厂系统(附源码)

1&#xff0c;项目背景 在如今这个信息时代&#xff0c;“汽车维修管理系统” 这种维修方式已经为越来越多的人所接受。在这种背景之下&#xff0c;一个安全稳定并且强大的网络预约平台不可或缺&#xff0c;在这种成熟的市场需求的推动下&#xff0c;在先进的信息技术的支持下…

纯血鸿蒙APP实战开发——边缓存边播放案例

介绍 OhosVideoCache是一个支持边播放边缓存的库&#xff0c;只需要将音视频的url传递给OhosVideoCache处理之后再设置给播放器&#xff0c; OhosVideoCache就可以一边下载音视频数据并保存在本地&#xff0c;一边读取本地缓存返回给播放器&#xff0c;使用者无需进行其他操作…

函数的MC/DC代码覆盖率

函数的MC/DC&#xff08;Modified Condition/Decision Coverage&#xff09;代码覆盖率是一种软件测试覆盖率指标&#xff0c;它特别关注于在决策&#xff08;如if-else语句&#xff09;中条件和决策本身的测试。MC/DC 覆盖率旨在确保每个条件在决策中至少被评估为真和假一次&a…