SpringBoot切面Aop的demo简单讲解
2021-01-16 04:18
标签:依赖 多版本 cat tag fastjson XML return 完整 elastic 本篇文章主要介绍的是SpringBoot切面Aop的demo简单讲解。 说明:如果想直接获取工程那么可以直接跳到底部,通过链接下载工程代码。 一、概念 AOP(Aspect OrientedProgramming):面向切面编程,面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。 二、用途 日志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理。 三、详解 1.切面(Aspect): 2.连接点(Joinpoint): 3.通知(Advice): 4.切入点(Pointcut) 注:以上的理论知识参考:https://www.cnblogs.com/yepei/p/4735298.html 环境要求 JDK:1.8 SpringBoot:2.2.6.RELEASE 首先还是Maven的相关依赖,基本和普通springboot项目一样,就是多了 pom.xml文件如下: SpringBoot在使用切面的时候,只需要在自定义的一个切面类中加上 这里我们就将切入点设置为控制层包里所有的请求。 切入点代码示例: 然后在定义一个前置通知,实现对请求参数的数据解密,这里我们就用User这个实体类的名称,对该数据进行解密。实际在运用是可以根据自身的情况来编写。 前置通知代码示例: 在编写完前置通知的方法之后,我们在编写后置通知的代码,这块基本和前置通知的一样,就是把返回的数据进行加密而已。 后置通知代码示例: 完整代码示例: 实体类代码 控制层z这块的代码和普通的一样,我们这里只需简单的做下处理即可,这里为了方便理解,没有编写service层和dao的代码。: ** 控制层代码** App 入口 和普通的SpringBoot项目基本一样! 代码如下: 编写完代码之后,我们启动程序,因为是Get请求,在浏览器或者使用Postman输入地址都可以进行测试,需要注意的是这里我们需要对name的值进行base64加密请求。 输入: http://localhost:8180/api/user?name=eHV3dWppbmc= 控制台打印: 前置通知接受的参数:{"name":"eHV3dWppbmc="} 请求响应参数: { 示例图: 关于SpringBoot切面Aop的demo简单讲解的文章就讲解到这里了,如有不妥,欢迎指正! SpringBoot 的aop的项目工程地址: SpringBoot整个集合的地址: springBoot配置文件的读取以及过滤器和拦截器的使用 SpringBoot的Restful风格的服务 SpringBoot+Mybatis+ Druid+PageHelper实现多数据源并分页 SpringBoot整合ElasticSearch实现多版本的兼容 SpringBoot整合Kafka和Storm SpringBoot整合Jsp和Thymeleaf SpringBoot整合Netty并使用Protobuf进行数据传输 SpringBoot简单打包部署 SpringBoot整合Redis使用Restful风格实现CRUD功能 SpringBoot优雅的全局异常处理 SpringBoot项目实现文件上传和邮件发送 SpringBoot整合Swagger和Actuator SpringBoot事物Transaction实战讲解教程 翩若惊鸿,婉若游龙,荣曜秋菊,华茂春松。仿佛兮若轻云之蔽月,飘飘兮若流风之回雪。远而望之,皎若太阳升朝霞;迫而察之,灼若芙蕖出渌波。--网易云网友评论 原创不易,如果感觉不错,希望给个推荐!您的支持是我写作的最大动力! SpringBoot切面Aop的demo简单讲解 标签:依赖 多版本 cat tag fastjson XML return 完整 elastic 原文地址:https://www.cnblogs.com/xuwujing/p/12927081.html前言
SpringBoot Aop
切面(Aop)
官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如:AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。“切面”在ApplicationContext中aop:aspect来配置。
程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者BServiceImpl.barB(String _msg, int _type)抛出异常等行为。
“切面”对于某个“连接点”所产生的动作,例如,TestAspect中对com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。其中,一个“切面”可以包含多个“Advice”,例如TestAspect。Advice共有如下5种类型:
匹配连接点的断言,在AOP中通知和一个切入点表达式关联。例如,TestAspect中的所有通知所关注的连接点,都由切入点表达式execution(* com.spring.service..(..))来决定。开发准备
spring-boot-starter-aop
这jar的依赖。application.properties
的文件的配置:banner.charset=UTF-8
server.tomcat.uri-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.messages.encoding=UTF-8
spring.application.name=springboot-aspect
server.port=8180
代码编写
@Aspect
注解进行声明,然后在自定义切面的类方法中加上对应的注解即可。
比如这里的示例我们想做一个请求响应的加解密切面处理,业务层只需关心代码逻辑实现,而不用关心请求参数和响应参数的加解密实现。那么首先我们需要自定义一个加解密的切面类,在该类添加@Aspect
注解,然后在定义一个公共的切入点(Pointcut),指向需要处理的包,然后在定义一个前置通知(添加@Before
注解)和后置通知(添加@AfterReturning
)方法实现即可。
@Pointcut("execution(public * com.pancm.web.*.*(..))")
public void doOperation() {
}
@Before("doOperation()")
public void before(JoinPoint joinPoint) throws Throwable{
Object[] objs = joinPoint.getArgs();
for (Object obj : objs) {
User user =(User) obj;
System.out.println("前置通知接受的参数:"+user);
String name =base64DeStr(user.getName());
user.setName(name);
}
}
@AfterReturning(returning = "object", pointcut = "doOperation()")
public void doAfterReturning(Object object) {
ResultBody resultBody = (ResultBody) object;
String str =null;
try {
str=base64EnStr(resultBody.getResult());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
resultBody.setResult(str);
System.out.println("后通知响应的参数:"+resultBody);
}
@Aspect
@Component
public class ParamAspect {
@Pointcut("execution(public * com.pancm.web.*.*(..))")
public void doOperation() {
}
@Before("doOperation()")
public void before(JoinPoint joinPoint) throws Throwable{
Object[] objs = joinPoint.getArgs();
for (Object obj : objs) {
User user =(User) obj;
System.out.println("前置通知接受的参数:"+user);
String name =base64DeStr(user.getName());
user.setName(name);
}
}
@AfterReturning(returning = "object", pointcut = "doOperation()")
public void doAfterReturning(Object object) {
ResultBody resultBody = (ResultBody) object;
String str =null;
try {
str=base64EnStr(resultBody.getResult());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
resultBody.setResult(str);
System.out.println("前置通知响应的参数:"+resultBody);
}
public String base64EnStr(String str) throws UnsupportedEncodingException {
return Base64.getEncoder().encodeToString(str.getBytes("UTF-8"));
}
public static String base64DeStr(String encodeStr) throws UnsupportedEncodingException {
byte[] decodeStr = Base64.getDecoder().decode(encodeStr);
return new String(decodeStr, "UTF-8");
}
public class User {
private Long id;
private String name;
private Integer age;
//getter 和 setter 略
}
@RestController
@RequestMapping(value = "/api")
public class UserRestController {
@GetMapping("/user")
public ResultBody findByUser(User user) {
System.out.println("用户查询接口请求的参数:"+user);
ResultBody resultBody = new ResultBody();
List
@SpringBootApplication
public class AspectApp
{
public static void main( String[] args )
{
SpringApplication.run(AspectApp.class, args);
System.out.println("Aspect启动成功!");
}
}
功能测试
用户查询接口请求的参数:{"name":"xuwujing"}
用户查询接口响应的参数:{"code":"0","result":"[{"age":18,"id":1,"name":"xuwujing"}]"}
后通知响应的参数:{"code":"0","result":"W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="}
"code": "0",
"message": null,
"result": "W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="
}其它
项目地址
https://github.com/xuwujing/springBoot-study/tree/master/springboot-aspect
https://github.com/xuwujing/springBoot-studySpringBoot整合系列的文章
音乐推荐
版权声明:
作者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm
个人博客出处:http://www.panchengming.com
下一篇:Manjaro内核编译
文章标题:SpringBoot切面Aop的demo简单讲解
文章链接:http://soscw.com/index.php/essay/42558.html