前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >12. AOP入门案例

12. AOP入门案例

作者头像
捞月亮的小北
发布2023-12-01 10:19:02
1180
发布2023-12-01 10:19:02
举报
文章被收录于专栏:捞月亮的小北

1. 需求分析

案例设定:测算接口执行效率,但是这个案例稍微复杂了点,我们对其进行简化。

简化设定:在方法执行前输出当前系统时间。

对于 SpringAOP 的开发有两种方式,XML 和 注解,我们使用哪个呢?

因为现在注解使用的比较多,所以本次课程就采用注解完成 AOP 的开发。

总结需求为:使用 SpringAOP 的注解方式完成在方法执行的前打印出当前系统时间。

2. 思路分析

需求明确后,具体该如何实现,都有哪些步骤,我们先来分析下:

1.导入坐标(pom.xml) 2.制作连接点(原始操作,Dao 接口与实现类) 3.制作共性功能(通知类与通知) 4.定义切入点 5.绑定切入点与通知关系(切面)

3. 环境准备

创建一个 Maven 项目

pom.xml 添加 Spring 依赖

代码语言:javascript
复制
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.10.RELEASE</version>
    </dependency>
</dependencies>

添加 BookDao 和 BookDaoImpl 类

代码语言:javascript
复制
public interface BookDao {
    public void save();
    public void update();
}

@Repository
public class BookDaoImpl implements BookDao {

    public void save() {
        System.out.println(System.currentTimeMillis());
        System.out.println("book dao save ...");
    }

    public void update(){
        System.out.println("book dao update ...");
    }
}

创建 Spring 的配置类

代码语言:javascript
复制
@Configuration
@ComponentScan("com.itheima")
public class SpringConfig {
}

编写 App 运行类

代码语言:javascript
复制
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = ctx.getBean(BookDao.class);
        bookDao.save();
    }
}

最终创建好的项目结构如下:

image
image

说明:

  • 目前打印 save 方法的时候,因为方法中有打印系统时间,所以运行的时候是可以看到系统时间
  • 对于 update 方法来说,就没有该功能
  • 我们要使用 SpringAOP 的方式在不改变 update 方法的前提下让其具有打印系统时间的功能。

4. AOP 实现步骤

步骤 1:添加依赖

pom.xml

代码语言:javascript
复制
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

image
image

  • 因为spring-context​ 中已经导入了spring-aop​,所以不需要再单独导入spring-aop
  • 导入 AspectJ 的 jar 包,AspectJ 是 AOP 思想的一个具体实现,Spring 有自己的 AOP 实现,但是相比于 AspectJ 来说比较麻烦,所以我们直接采用 Spring 整合 ApsectJ 的方式进行 AOP 开发。
步骤 2:定义接口与实现类
代码语言:javascript
复制
环境准备的时候,BookDaoImpl已经准备好,不需要做任何修改
步骤 3:定义通知类和通知

通知就是将共性功能抽取出来后形成的方法,共性功能指的就是当前系统时间的打印。

代码语言:javascript
复制
public class MyAdvice {
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

类名和方法名没有要求,可以任意。

步骤 4:定义切入点

BookDaoImpl 中有两个方法,分别是 save 和 update,我们要增强的是 update 方法,该如何定义呢?

代码语言:javascript
复制
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

说明:

  • 切入点定义依托一个不具有实际意义的方法进行,即无参数、无返回值、方法体无实际逻辑。
  • execution 及后面编写的内容,后面会有章节专门去学习。
步骤 5:制作切面

切面是用来描述通知和切入点之间的关系,如何进行关系的绑定?

代码语言:javascript
复制
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}

    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}

绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置

image
image

说明:@Before 翻译过来是之前,也就是说通知会在切入点方法执行之前执行,除此之前还有其他四种类型,后面会讲。

步骤 6:将通知类配给容器并标识其为切面类
代码语言:javascript
复制
@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}

    @Before("pt()")
    public void method(){
        System.out.println(System.currentTimeMillis());
    }
}
步骤 7:开启注解格式 AOP 功能
代码语言:javascript
复制
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
步骤 8:运行程序
代码语言:javascript
复制
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao = ctx.getBean(BookDao.class);
        bookDao.update();
    }
}

看到在执行 update 方法之前打印了系统时间戳,说明对原始方法进行了增强,AOP 编程成功。

image
image

知识点 1:@EnableAspectJAutoProxy

名称

@EnableAspectJAutoProxy

类型

配置类注解

位置

配置类定义上方

作用

开启注解格式 AOP 功能

知识点 2:@Aspect

名称

@Aspect

类型

类注解

位置

切面类定义上方

作用

设置当前类为 AOP 切面类

知识点 3:@Pointcut

名称

@Pointcut

类型

方法注解

位置

切入点方法定义上方

作用

设置切入点方法

属性

value(默认):切入点表达式

知识点 4:@Before

名称

@Before

类型

方法注解

位置

通知方法定义上方

作用

设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前运行

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 需求分析
  • 2. 思路分析
  • 3. 环境准备
  • 4. AOP 实现步骤
    • 步骤 1:添加依赖
      • 步骤 2:定义接口与实现类
        • 步骤 3:定义通知类和通知
          • 步骤 4:定义切入点
            • 步骤 5:制作切面
              • 步骤 6:将通知类配给容器并标识其为切面类
                • 步骤 7:开启注解格式 AOP 功能
                  • 步骤 8:运行程序
                  • 知识点 1:@EnableAspectJAutoProxy
                  • 知识点 2:@Aspect
                  • 知识点 3:@Pointcut
                  • 知识点 4:@Before
                  相关产品与服务
                  容器服务
                  腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档