AOP简介

面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP的延续。简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理技术,在不修改源码的基础上,对我们已有的方法进行增强。

相关概念

Joinpoint(连接点)

所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只支持方法类型的连接点。

Pointcut(切入点)

所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。

Advice(通知/增强)

所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。

通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。

Introduction(引介)

引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方法或 Field。

Target(目标对象)

代理的目标对象。

Weaving(织入)

是指把增强应用到目标对象来创建新的代理对象的过程。

Proxy(代理)

一个类被 AOP 织入增强后,就产生一个结果代理类。

Aspect(切面)

是切入点和通知(引介)的结合。

在spring 中,框架会根据目标类是否实现了接口来决定采用哪种动态代理的方式。

在spring 中,2.0默认采用CGLIB代理,如果需要基于接口的动态代理(JDK基于接口的动态代理) ,需要设置spring.aop.proxy-target-class属性为false。

spring的动态代理,借用了AspectJ的注解。

引入依赖

        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Controller层编写

@Controller
@RequestMapping("aspect")
@Api(tags = "切面")
public class AspectController { @ApiOperation("切面通知")
@RequestMapping(value = "/sayHello",method = RequestMethod.GET)
@ResponseBody
public Object sayHello(String name){
System.out.println("---------------------方法执行----------------");
return "hello " + name;
} }

切面类编写

@Aspect //表示当前类是一个切面类
@Component
@Slf4j
public class AspectConfig { /**
* 定义切入点,切入点为com.yxkj.springbootdemo.controller下的所有函数
*
**/
@Pointcut("execution(public * com.yxkj.springbootdemo.controller..*.*(..))")
public void root(){} //当前方法是异常通知
@AfterThrowing("root()")
public void rollback() {
log.info("当前方法是一个异常通知");
} //当前方法是最终通知
@After("root()")
public void release() {
log.info("当前方法是一个最终通知");
} //环绕通知
@Around("root()")
public Object transactionAround(ProceedingJoinPoint pjp) throws Throwable {
//定义返回值
Object rtValue = null;
//获取方法执行所需的参数
Object[] args = pjp.getArgs();
log.info("环绕通知执行方法前,传入参数"+args[0]);
//执行方法
rtValue = pjp.proceed(args);
log.info("环绕通知执行方法后,传出参数"+rtValue);
return rtValue;
} @Before("root()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); // 记录下请求内容
log.info("前置通知:URL : " + request.getRequestURL().toString());
log.info("前置通知:HTTP_METHOD : " + request.getMethod());
log.info("前置通知:IP : " + request.getRemoteAddr());
log.info("前置通知:CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
log.info("前置通知:传入参数 : " + Arrays.toString(joinPoint.getArgs())); } @AfterReturning(returning = "ret", pointcut = "root()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
log.info("后置通知:返回参数 : " + ret);
} }

访问方法结果

13 08:50:25.453 INFO ||:环绕通知执行方法前,传入参数123213
13 08:50:25.454 INFO ||:前置通知:URL : http://127.0.0.1:8088/springbootdemo/aspect/sayHello
13 08:50:25.454 INFO ||:前置通知:HTTP_METHOD : GET
13 08:50:25.454 INFO ||:前置通知:IP : 127.0.0.1
13 08:50:25.455 INFO ||:前置通知:CLASS_METHOD : com.yxkj.springbootdemo.controller.AspectController.sayHello
13 08:50:25.455 INFO ||:前置通知:传入参数 : [123213]
---------------------方法执行----------------
13 08:50:25.457 INFO ||:后置通知:返回参数 : hello 123213
13 08:50:25.457 INFO ||:当前方法是一个最终通知
13 08:50:25.457 INFO ||:环绕通知执行方法后,传出参数hello 123213

Gitee地址

https://gitee.com/zhuayng/foundation-study/blob/develop/SpringBootDemo/src/main/java/com/yxkj/springbootdemo/config/AspectConfig.java

SpringBoot集成AOP的更多相关文章

  1. springboot集成AOP管理日志

    如何将所有的通过url的请求参数以及返回结果都输出到日志中? 如果在controller的类中每个方法名都写一个log输出肯定是不明智的选择. 使用spring的AOP功能即可完成. 1. 在pom. ...

  2. springboot集成aop日志

    日常开发中假如是前后端完全分离,我们会习惯用浏览器去调用controller的接口来测试.这一个过程普通的日志功能会记录sql参数等一些基本信息.但是假如项目越来越庞大,我们的包越来越多,在维护项目和 ...

  3. SpringBoot 源码解析 (十)----- Spring Boot的核心能力 - 集成AOP

    本篇主要集成Sping一个重要功能AOP 我们还是先回顾一下以前Spring中是如何使用AOP的,大家可以看看我这篇文章spring5 源码深度解析----- AOP的使用及AOP自定义标签 Spri ...

  4. SpringBoot 集成Log4j、集成AOP

    集成Log4j (1)在pom.xml中添加依赖 <!--去掉springboot默认的日志--> <dependency> <groupId>org.spring ...

  5. Springboot的日志管理&Springboot整合Junit测试&Springboot中AOP的使用

    ==============Springboot的日志管理============= springboot无需引入日志的包,springboot默认已经依赖了slf4j.logback.log4j等日 ...

  6. springboot集成shiro实现权限认证

    github:https://github.com/peterowang/shiro 基于上一篇:springboot集成shiro实现身份认证 1.加入UserController package ...

  7. SpringBoot集成PageHelper时出现“在系统中发现了多个分页插件,请检查系统配置!”

    近日在项目中使用SpringBoot集成PageHelper后,跑单元测试时出现了"在系统中发现了多个分页插件,请检查系统配置!"这个问题. 如下图所示: org.mybatis. ...

  8. SpringBoot集成Shiro 实现动态加载权限

    一.前言 本文小编将基于 SpringBoot 集成 Shiro 实现动态uri权限,由前端vue在页面配置uri,Java后端动态刷新权限,不用重启项目,以及在页面分配给用户 角色 . 按钮 .ur ...

  9. springBoot 集成Mysql数据库

    springBoot 集成Mysql数据库 前一段时间,我们大体介绍过SpringBoot,想必大家还有依稀的印象.我们先来回顾一下:SpringBoot是目前java世界最流行的一个企业级解决方案框 ...

随机推荐

  1. 【C++】关键字回忆leetcode题解

    20200515 前缀和 no.560 20200518 动态规划 no.152 20200520 状态压缩 no.1371 20200521 中心扩散 no.5 20200523 滑动窗口 no.7 ...

  2. Counterfactual VQA: A Cause-Effect Look at Language Bias

    目录 概 主要内容 实现 代码 Niu Y., Tang K., Zhang H., Lu Z., Hua X. and Wen J. Counterfactual VQA: A Cause-Effe ...

  3. 编写Java程序,现要求使用 dom4j 解析 city.xml 文档,实现省份及对应城市的联动特效,效果如图所示

    查看本章节 查看作业目录 需求说明: 现要求使用 dom4j 解析 city.xml 文档,实现省份及对应城市的联动特效,效果如图所示 实现思路: 创建解析 XML 文档类 ParseXML 和窗体类 ...

  4. javascript实现base64格式转码与解码

    最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码! 然后查了一下, ...

  5. 开源实践 | 携程在OceanBase的探索与实践

    写在前面:选型考虑 携程于1999年创立,2016-2018年全面推进应用 MySQL 数据库,前期线上业务.前端技术等以 SQL Server 为主,后期数据库逐步从 SQL Server 转到开源 ...

  6. windows更改pip源(可用)

    中国科学技术大学 : https://pypi.mirrors.ustc.edu.cn/simple 清华:https://pypi.tuna.tsinghua.edu.cn/simple 豆瓣:ht ...

  7. prtotype原型对象

    js每个对象都拥有一个原型对象,每个对象都能从原型对象继承方法和属性,原型链就是基于原型对象而产生的, 也就是说,每个对象都能继承原型对象的方法和属性,这样一层一层的继承,就形成了原型链 当然,你也可 ...

  8. 【Java】IO

    文章目录 IO 说明 流的分类 关于相对路径 节点流 FileRead 对read()操作升级:使用read的重载方法 总结 FileWriter 复制操作 总结 FileInput(Output)S ...

  9. Redhat 如何使用yum 源(转)

    1.需要把Redhat注册的信息给解决掉 This system is not registered with an entitlement server. You can use subscript ...

  10. [开发笔记usbTOcan]软件需求分析和软件架构设计

    前面文章进行了系统分析和系统架构设计,手工焊接了一个板子,集合EK-TMC123GXL开发板(请忽略焊接技术) SWE.1 | 软件需求分析 软件需求分析过程的目的是将系统需求的软件相关部分转化为一组 ...