本篇文章主要介绍的是SpringBoot切面Aop的demo简单讲解。html
说明:若是想直接获取工程那么能够直接跳到底部,经过连接下载工程代码。java
1、概念git
AOP(Aspect OrientedProgramming):面向切面编程,面向切面编程(也叫面向方面编程),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP能够对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度下降,提升程序的可重用性,同时提升了开发的效率。github
2、用途web
日志记录,性能统计,安全控制,权限管理,事务处理,异常处理,资源池管理。spring
3、详解编程
1.切面(Aspect):
官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如:AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。“切面”在ApplicationContext中aop:aspect来配置。json
2.链接点(Joinpoint):
程序执行过程当中的某一行为,例如,AServiceImpl.barA()的调用或者BServiceImpl.barB(String _msg, int _type)抛出异常等行为。api
3.通知(Advice):
“切面”对于某个“链接点”所产生的动做,例如,TestAspect中对com.spring.service包下全部类的方法进行日志记录的动做就是一个Advice。其中,一个“切面”能够包含多个“Advice”,例如TestAspect。Advice共有以下5种类型:浏览器
4.切入点(Pointcut)
匹配链接点的断言,在AOP中通知和一个切入点表达式关联。例如,TestAspect中的全部通知所关注的链接点,都由切入点表达式execution(* com.spring.service..(..))来决定。
注:以上的理论知识参考:http://www.javashuo.com/article/p-xwxfjphd-bt.html
环境要求
JDK:1.8
SpringBoot:2.2.6.RELEASE
首先仍是Maven的相关依赖,基本和普通springboot项目同样,就是多了spring-boot-starter-aop
这jar的依赖。
pom.xml文件以下:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>test</scope> </dependency> </dependencies>
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
SpringBoot在使用切面的时候,只须要在自定义的一个切面类中加上 @Aspect
注解进行声明,而后在自定义切面的类方法中加上对应的注解便可。
好比这里的示例咱们想作一个请求响应的加解密切面处理,业务层只需关心代码逻辑实现,而不用关心请求参数和响应参数的加解密实现。那么首先咱们须要自定义一个加解密的切面类,在该类添加@Aspect
注解,而后在定义一个公共的切入点(Pointcut),指向须要处理的包,而后在定义一个前置通知(添加@Before
注解)和后置通知(添加@AfterReturning
)方法实现便可。
这里咱们就将切入点设置为控制层包里全部的请求。
切入点代码示例:
@Pointcut("execution(public * com.pancm.web.*.*(..))") public void doOperation() { }
而后在定义一个前置通知,实现对请求参数的数据解密,这里咱们就用User这个实体类的名称,对该数据进行解密。实际在运用是能够根据自身的状况来编写。
前置通知代码示例:
@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 略 }
控制层z这块的代码和普通的同样,咱们这里只需简单的作下处理便可,这里为了方便理解,没有编写service层和dao的代码。:
** 控制层代码**
@RestController @RequestMapping(value = "/api") public class UserRestController { @GetMapping("/user") public ResultBody findByUser(User user) { System.out.println("用户查询接口请求的参数:"+user); ResultBody resultBody = new ResultBody(); List<User> userList =new ArrayList<>(); User user2=new User(); user2.setId(1L); user2.setName("xuwujing"); user2.setAge(18); userList.add(user2); resultBody.setCode("0"); resultBody.setResult(userList.toString()); System.out.println("用户查询接口响应的参数:"+resultBody); return resultBody; } }
App 入口
和普通的SpringBoot项目基本同样!
代码以下:
@SpringBootApplication public class AspectApp { public static void main( String[] args ) { SpringApplication.run(AspectApp.class, args); System.out.println("Aspect启动成功!"); } }
编写完代码以后,咱们启动程序,由于是Get请求,在浏览器或者使用Postman输入地址均可以进行测试,须要注意的是这里咱们须要对name的值进行base64加密请求。
输入:
控制台打印:
前置通知接受的参数:{"name":"eHV3dWppbmc="}
用户查询接口请求的参数:{"name":"xuwujing"}
用户查询接口响应的参数:{"code":"0","result":"[{"age":18,"id":1,"name":"xuwujing"}]"}
后通知响应的参数:{"code":"0","result":"W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="}
请求响应参数:
{
"code": "0",
"message": null,
"result": "W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="
}
示例图:
关于SpringBoot切面Aop的demo简单讲解的文章就讲解到这里了,若有不妥,欢迎指正!
SpringBoot 的aop的项目工程地址:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-aspect
SpringBoot整个集合的地址:
https://github.com/xuwujing/springBoot-study
翩若惊鸿,婉若游龙,荣曜秋菊,华茂春松。仿佛兮若轻云之蔽月,飘飘兮若流风之回雪。远而望之,皎若太阳升朝霞;迫而察之,灼若芙蕖出渌波。--网易云网友评论
原创不易,若是感受不错,但愿给个推荐!您的支持是我写做的最大动力!
版权声明:
做者:虚无境
博客园出处:http://www.cnblogs.com/xuwujing
CSDN出处:http://blog.csdn.net/qazwsxpcm
我的博客出处:http://www.panchengming.com