Spring AOP 注解及使用示例
本文内容纲要:
- 什么是 AOP- AOP 术语
- 通过注解声明切点指示器
- 通过注解声明 5 种通知类型
- AOP 示例
什么是 AOP
AOP是Spring框架面向切面的编程思想,AOP采用一种称为“横切”的技术,将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定的位置中。
切面:相当于应用对象间的横切点,我们可以将其单独抽象为单独的模块
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(..))")
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访问结果
控制台日志输出结果
本文内容总结:什么是 AOP,AOP 术语,通过注解声明切点指示器,通过注解声明 5 种通知类型,AOP 示例,
原文链接:https://www.cnblogs.com/suphowe/p/12098042.html
以上是 Spring AOP 注解及使用示例 的全部内容, 来源链接: utcz.com/z/296948.html