Spring AOP 注解及使用示例

本文内容纲要:

- 什么是 AOP

- AOP 术语

- 通过注解声明切点指示器

- 通过注解声明 5 种通知类型

- AOP 示例

什么是 AOP

AOP是Spring框架面向切面的编程思想,AOP采用一种称为“横切”的技术,将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定的位置中。

切面:相当于应用对象间的横切点,我们可以将其单独抽象为单独的模块

Image

AOP 术语

AOP 领域中的特性术语:

  • 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
  • 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
  • 切点(PointCut): 可以插入增强处理的连接点。
  • 切面(Aspect): 切面是通知和切点的结合。
  • 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
  • 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入

通过注解声明切点指示器

AspectJ指示器描述
arg()限制连接点匹配参数为指定类型的执行方法
@args()限制连接点匹配参数由指定注解标注的执行方法
execution()用于匹配是连接点的执行方法
this()限制连接点匹配AOP 代理的Bean 引用为指定类型的类
target()限制连接点匹配目标对象为指定类型的类
@target()限制连接点匹配特定的执行对象.这些对象对应的类要具备指定类型的注解
within()限制连接点匹配指定的类型
@within()限制连接点匹配指定注解所标注的类型(当使用Spring AOP时,方法定义在由指定的注解所标注的类里)
@annotation()限制匹配带有指定注解连接点

通过注解声明 5 种通知类型

注解描述
@Before通知方法会在目标方法调用之前执行
@After通知方法会在目标方法返回或异常后调用
@AfterReturning通知方法会在目标方法返回后调用
@AfterThrowing通知方法会在目标方法抛出异常后调用
@Around通知方法会将目标方法封装起来

@Pointcut   //定义切点位置

使用:

@Pointcut("execution(* com.springinaction.springidol.Instrument.play(..))")

Image

AOP 示例

下列代码基于SpringBoot 工程,部分代码已省略,请自行创建

1.创建AopController.java

package com.soft.controller;

import com.google.gson.Gson;

import com.soft.service.IAopService;

import io.swagger.annotations.Api;

import io.swagger.annotations.ApiImplicitParam;

import io.swagger.annotations.ApiImplicitParams;

import io.swagger.annotations.ApiOperation;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.ResponseBody;

import org.springframework.web.bind.annotation.RestController;

/**

* Aop测试

* @description: AopController

* @author: suphowe

* @create: 2019-12-25 14:46

**/

@RestController

@RequestMapping("/aop")

@Api(value = "Aop切面编程测试")

public class AopController {

@Autowired

private IAopService aopService;

@ResponseBody

@RequestMapping(value = "/method_one", method = RequestMethod.POST)

@ApiOperation(value = "方法1", notes = "")

@ApiImplicitParams({

@ApiImplicitParam(paramType = "query", name = "msg", value = "msg", required = false, dataType = "String")

})

public String method_one(String msg){

String result = aopService.method_one(msg);

return result;

}

}

2.创建 IAopService.java 和 AopServiceImpl.java

package com.soft.service;

public interface IAopService {

String method_one(String msg);

}

package com.soft.service.impl;

import com.soft.service.IAopService;

import org.springframework.stereotype.Service;

@Service

public class AopServiceImpl implements IAopService {

@Override

public String method_one(String msg){

System.out.println("==>接收信息:" + msg);

return "return method_one";

}

}

3.创建 SysAspect.java

package com.soft.aspect;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.*;

import org.springframework.stereotype.Component;

@Aspect

@Component

public class SysAspect {

/**

* 声明切点

*/

@Pointcut("execution(* com.soft.service.*.*(..))")

public void point(){}

/**

* 通知方法会在目标方法调用之前执行

*/

@Before("point())")

public void before() {

System.out.println("before ==> 通知方法会在目标方法调用之前执行");

}

/**

* 通知方法会在目标方法返回或异常后调用

*/

@After("point()")

public void after() {

System.out.println("After ==> 通知方法会在目标方法返回或异常后调用");

}

/**

* 通知方法会在目标方法返回后调用

*/

@AfterReturning("point()")

public void afterReturing() {

System.out.println("AfterReturning ==> 通知方法会在目标方法返回后调用");

}

/**

* 通知方法会在目标方法抛出异常后调用

*/

@AfterThrowing("point()")

public void afterThrowing() {

System.out.println("AfterThrowing ==> 通知方法会在目标方法抛出异常后调用");

}

/**

* 通知方法会将目标方法封装起来

* @param proceeding

*/

@Around("point()")

public Object around(ProceedingJoinPoint proceeding) throws Exception{

//和JoinPoint一样,ProceedingJoinPoint也可以获取

//连接点方法的实参

Object[] args=proceeding.getArgs();

//连接点方法的方法名

String methodName=proceeding.getSignature().getName();

//连接点方法所在的对象

Object targetObj=proceeding.getTarget();

String targetClassName=targetObj.getClass().getName();

Object result=null;

try {

System.out.println("前置通知==>参数:" + args[0]);

System.out.println("前置通知==>执行方法:" + methodName);

//执行连接点的方法 获取返回值

result=proceeding.proceed(args);

System.out.println("返回通知==>返回结果:" + result);

}catch (Throwable e) {

System.out.println("异常通知==>" + e);

}finally {

System.out.println("最终通知==>执行结束");

}

return result;

}

}

4.启动工程,通过Swagger-ui.html访问

swagger访问结果

Image

控制台日志输出结果

Image

本文内容总结:什么是 AOP,AOP 术语,通过注解声明切点指示器,通过注解声明 5 种通知类型,AOP 示例,

原文链接:https://www.cnblogs.com/suphowe/p/12098042.html

以上是 Spring AOP 注解及使用示例 的全部内容, 来源链接: utcz.com/z/296948.html

回到顶部