springboot入门到精通(九)springboot面向切面编程

导读:本篇文章讲解 springboot入门到精通(九)springboot面向切面编程,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

springboot面向切面编程

目录

1介绍
2springboot初体验
3springboot集成jsp
4springboot属性注入
5springboot集成mybatis
6springboot集成lombok
7springboot集成logback日志
8springboot开启全局热部署
9springboot面向切面编程
10springboot文件上传
11springboot文件下载
12springboot自定义拦截器
13springboot打成war包发布
14springboot打成jar包发布
15springboot自定义banner
16springboot配置文件拆分

什么是面向切面编程

  • 全称Aspect Oriented Programming,面向切面编程,简称aop。
  • 通俗理解是这样,我们有很多方法都要做一件相同的事情,我们可以把这件事情单独拿出来写个方法,通过aop方式,我们可以让指定的
    方法去使用我们单独拿出来的这个方法。通常项目中,操作日志就是通过aop实现的。

基本概念

  • @Aspect:作用在类上,代表这个类是一个切面配置类

通知的方式

  • @Before:前置通知,作用在方法上,执行目标方法之前会进入前置通知
  • @After:后置通知,作用在方法上,执行目标方法之后会进入后置通知
  • @Around:环绕通知,作用在方法上,执行目标方法之前会进入环绕通知,环绕通知放行之后会执行目标方法,目标方法执行完之后会再进入环绕通知

切入点表达式

3个通知都有value属性,可以自定义切入点表达式,我们主要使用execution和within

  • execution:方法级别,精确到每个方法
  • within:类级别,精确到类,效率高。如果我们要作用在整个类上,就用within
    ::: warning 注意
    推荐使用within,效率高,并且切入点表达式好写,我们只要指向某些类就行了。本节不讲具体的表达式如何写,想要了解更多内容请自行了解。
    :::

顺序控制

@order:可以用在类上,也可以用在方法上,value属性,数字越小越先执行(经测试,加在方法上无效)

获取执行方法对象

在 @Before和@After方法里面,我们使用JoinPoint,在@Around方法里面,我们使用ProceedingJoinPoint

System.out.println("当前执行的方法名:"+joinPoint.getSignature().getName());
System.out.println("当前执行的方法所在类的全包名:"+joinPoint.getSignature().getDeclaringTypeName());
System.out.println("当前的目标对象:"+joinPoint.getTarget());
System.out.println("当前参数对象(是一个数组):"+joinPoint.getArgs());

::: tip 提示
注解里面的value属性可以省略,直接写值,比如@Before(value = "within(com.moyundong.controller.*Controller)")可以写成
@Before("within(com.moyundong.controller.*Controller)")@Order(value = 1)可以写成@Order(1)
:::

如何使用

  1. 添加依赖
    <!--开启aop所需的依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
  1. 创建类MyAspect1,
  • 2.1类上添加@Aspect、@Component注解,
  • 2.2创建3个测试方法,分别对应@Before、@After和@Around
  • 2.3切入点表达式value = "within(com.moyundong.controller.*Controller)"表示com.moyundong.controller包下所有以Controller
    结尾的类里面的所有方法都受影响。
  • 使用JoinPoint或者ProceedingJoinPoint获取了当前执行方法的相关信息。
@Aspect
@Component
@Order(value = 1)
public class MyAspect1 {
    @Before(value = "within(com.moyundong.controller.*Controller)")
    public void afterTest(JoinPoint joinPoint){
        System.out.println("************前置通知MyAspect1*****************");
        System.out.println("当前执行的方法名:"+joinPoint.getSignature().getName());
        System.out.println("当前执行的方法所在类的全包名:"+joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("当前的目标对象:"+joinPoint.getTarget());
        System.out.println("当前参数对象(是一个数组):"+joinPoint.getArgs());
    }

    @After(value = "within(com.moyundong.controller.*Controller)")
    public void beforTest(JoinPoint joinPoint){
        System.out.println("************后置通知MyAspect1*****************");
        System.out.println("当前执行的方法名:"+joinPoint.getSignature().getName());
        System.out.println("当前执行的方法所在类的全包名:"+joinPoint.getSignature().getDeclaringTypeName());
        System.out.println("当前的目标对象:"+joinPoint.getTarget());
        System.out.println("当前参数对象(是一个数组):"+joinPoint.getArgs());
    }

    @Around(value = "within(com.moyundong.controller.*Controller)")
    public Object arountTest(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("*****************在目标方法执行前,进入环绕通知MyAspect1***************************");
        System.out.println("当前执行的方法名:"+proceedingJoinPoint.getSignature().getName());
        System.out.println("当前执行的方法所在类的全包名:"+proceedingJoinPoint.getSignature().getDeclaringTypeName());
        System.out.println("当前的目标对象:"+proceedingJoinPoint.getTarget());
        System.out.println("当前参数对象(是一个数组):"+proceedingJoinPoint.getArgs());
        try{
            //执行目标方法,并且得到返回值
            Object object = proceedingJoinPoint.proceed();
            System.out.println("*****************在目标方法执行后,再进入环绕通知MyAspect1***************************");
            //返回目标方法执行后的值
            return object;
        } catch (Throwable e){
            System.out.println("*****************在目标方法执行出现异常时处理***************************");
            return null;
        }
    }
}

测试

启动服务,在浏览器输入http://localhost:8088/moyundong/Test/hello来看看效果。
大家可以再创建个MyAspect2,内容和MyAspect1差不多,@Order值为2,重新运行程序看看效果。把MyAspect1和MyAspect2的order顺序调换下,再执行下看看效果。

本节示例下载地址:java相关demo下载列表

::: warning 注意
在不同的平台,文档显示的效果是不一样的,最佳最全观看地址:springboot面向切面编程
欢迎大家来博客了解更多内容:java乐园
:::

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/13523.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!