文章目录
- 一、提出任务
 - 二、采用配置方式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装饰器在简化代码和增强功能方面的强大能力。两种方式都提高了代码的可读性和可维护性,达到了良好的解耦效果。
 



















