IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Spring 面向切面编程 第1关:使用前后置通知统计所有方法的执行时间 -> 正文阅读

[Java知识库]Spring 面向切面编程 第1关:使用前后置通知统计所有方法的执行时间

目录

任务描述

相关知识

AOP基本概念

切点完整表达式

五种通知

实例解析

编程要求

测试说明

参考代码


任务描述

Spring AOPSpring框架的核心技术之一,不幸的是,AOP 中许多概念不是特别直观,因此,本关卡将使用代码案例的方式讲解 AOP相关概念。

本关任务:使用前后置通知统计出博客系统中博客类中每个业务方法的执行时长。

相关知识

AOP基本概念

  • Aspect(切面): 切面由切点 (Pointcut) 和增强/通知 (Advice) 组成,它既包括了横切逻辑的定义、也包括了连接点的定义;

  • Joint point(连接点):能够被拦截的地方:Spring AOP 是基于动态代理的,所以是方法拦截的。每个成员方法都可以称之为连接点;

  • Pointcut(切点):具体定位的连接点,上面也说了,每个方法都可以称之为连接点,我们具体定位到某一个方法就成为切点;

  • Advice(通知/增强):表示添加到切点的一段逻辑代码,并定位连接点的方位信息。简单来说就定义了是干什么的,具体是在哪干;

  • Spring AOP提供了5Advice类型给我们,分别是:前置(Before)、后置(After)、返回(AfterReturning)、异常(AfterThrowing)、环绕(Around);

  • Target(目标对象):织入Advice的目标对象;

  • Weaving(织入):将增强/通知添加到目标类的具体连接点上的过程。

切点完整表达式

切点的完整表达式如下:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)

参数参数说明
modifiers-pattern修饰符 可选 public private protected
declaring-type-pattern方法的声明类型
name-patterm方法名称类型,例 set* 则表示以set开头的所有的方法名称
param-pattern参数匹配:(..) 表示任意多个参数,每个参数任意多个类型,(*,String) 表示两个参数,第一个是任意类型,第二个是String
throws-pattern异常的匹配模式
ret-type-pattern返回类型 必选 * 代表任意类型

五种通知

前置通知:在连接点前面执行,前置通知不会影响连接点的执行;

后置通知:在连接点执行完成后执行,不管是正常执行完成,还是抛出异常,都会执行返回通知中的内容;

异常返回通知:在连接点抛出异常后执行;

正常返回通知:在连接点正常执行完成后执行,如果连接点抛出异常,则不会执行;

环绕通知:最为强大的通知,它能够让你编写的逻辑将被通知的目标方法完全包裹起来。实际上就像在一个通知方法中同时编写前置通知和后置通知。定义通知的时候在通知方法中添加了入参ProceedingJoinPoint,这个参数是必须写的。因为需要在通知中使用ProceedingJoinPoint.proceed()调用目标方法。

  1. @Around("切点")
  2. public void around(ProceedingJoinPoint point) throws InterruptedException {
  3. //目标方法执行前
  4. System.out.println(" 环绕通知前");
  5. try {
  6. //执行目标方法
  7. point.proceed();
  8. } catch (Throwable throwable) {
  9. throwable.printStackT\frace();
  10. }
  11. //目标方法执行后
  12. System.out.println(" 环绕通知后");
  13. }

实例解析

看完AOP基本概念是不是感觉有点晦涩难懂?下面就让我们以实例讲解一下,比如企业招聘的时候,面试官只需要做面试打分相关的核心功能即可,简历筛选和入职相关步骤交给人力资源就可以了,又比如博客系统中用户(User类)有个修改用户名和密码的核心功能,但是在修改用户密码之前,我们会校验该用户是否具有权限,检验权限的地方有很多,我们把这一功能独立出来当成切面类,而User类只需实现修改用户名和密码方法即可,下面就让我们看一下具体是怎么实现的。

  • 创建目标类(待增强的目标对象):
  1. package Educoder;
  2. import org.springframework.stereotype.Component;
  3. @Component("User")
  4. public class User {
  5. public void updateNameAndPw() {
  6. System.out.println("用户-修改用户名和密码");
  7. }
  8. }
  • 创建切面类(包含切点execution(* Educoder.User.updateNameAndPw())和通知/增强before()方法):
  1. package Educoder;
  2. import org.aspectj.lang.annotation.*;
  3. import org.springframework.stereotype.Component;
  4. @Component("Authority")
  5. @Aspect
  6. public class Authority {
  7. //前置通知,括号内切点表达式的意思就是`Educoder`包下`User`类下的`updateNameAndPw()`方法
  8. @Before("execution(* Educoder.User.updateNameAndPw())")
  9. public void before() {
  10. System.out.println("权限校验");
  11. }
  12. }
  • applicationContext.xml中配置自动注入:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:aop="http://www.springframework.org/schema/aop"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!--表明 Educoder 包及其子包中,如果某个类的头上带有特定的注解
  10. @Component,@Repository,@Service等就会将这个对象作为 Bean 注册进Spring 容器 -->
  11. <context:component-scan base-package="Educoder" />
  12. <!--自动为spring容器中那些配置@aspectJ切面的 Bean 创建代理,织入切面。 -->
  13. <aop:aspectj-autoproxy/>
  14. </beans>
  • 编写测试代码:
  1. package Educoder;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class Test {
  5. public static void main(String[] args) {
  6. //创建Spring的IOC容器对象
  7. ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
  8. //从IoC的容器中获取Bean实例
  9. Interviewer spr1 = applicationContext.getBean("User", Interviewer.class);
  10. //调用updateNameAndPw()方法
  11. spr1.updateNameAndPw();
  12. }
  13. }
  • 输出结果如下:?权限校验?用户-修改用户名和密码

编程要求

请仔细阅读右侧代码,根据方法内的提示,在Begin - End区域内进行代码补充,把目标类(BlogService)中的所有方法的执行时间统计出来,目标类在右侧代码文件区域可见。 后台IoC容器对象会自动获取目标类实例并调用目标类中所有方法。

测试说明

补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。 预期输出:

当前时间2019.1.1 00:00:00

业务功能一

当前时间2019.1.1 00:01:00,执行耗时60000

当前时间2019.1.1 00:00:00

业务功能二

当前时间2019.1.1 00:01:00,执行耗时60000


开始你的任务吧,祝你成功!

参考代码

package Educoder;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.text.SimpleDateFormat;

@Component("BlogAdvice")
@Aspect
public class BlogAdvice {
    //定义切点
    @Pointcut("execution(* Educoder.BlogService.service*(..))")
    public void My() {
    }
	
	//定义前置通知,输出当前时间2019.1.1 00:00:00
    @Before("My()")
    public void before() {
        System.out.println("当前时间2019.1.1 00:00:00");
    }
    //定义后置通知,输出当前时间2019.1.1 00:01:00,执行耗时60000  
    @After("My()")
    public void after() {
    System.out.println("当前时间2019.1.1 00:01:00,执行耗时60000");
    }
}

?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-11-05 00:12:25  更:2022-11-05 00:16:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年3日历 -2025/3/10 18:38:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码