Spring Boot 整合 AOP
一、示例
1、依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
2、Controller
package com.aop.aop.controller; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController; @RestController
@RequestMapping("/aopController")
public class AopController { @RequestMapping(value="/sayHello", method=RequestMethod.GET)
public String sayHello(String name){
return "hello" + name;
} @RequestMapping(value="/sayHello2", method=RequestMethod.GET)
public String sayHello2(String name){
return "hello" + name;
}
}
3、定义切面类
package com.aop.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest;
import java.util.Arrays; @Aspect
@Component
public class WebLogAcpect {
private Logger logger = LoggerFactory.getLogger(WebLogAcpect.class); /**
* 定义切入点,切入点为com.aop.aop.controller下的所有函数
*/
@Pointcut("execution(public * com.aop.aop.controller..*.*(..))")
public void webLog(){} /**
* 前置通知:在连接点之前执行的通知
* @param joinPoint
* @throws Throwable
*/
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest(); // 记录下请求内容
logger.info("URL : " + request.getRequestURL().toString());
logger.info("HTTP_METHOD : " + request.getMethod());
logger.info("IP : " + request.getRemoteAddr());
logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
} @AfterReturning(returning = "ret",pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理完请求,返回内容
logger.info("RESPONSE : " + ret);
}
}
执行

小结:
1) 在完成引入AOP依赖包之后,一般并不需要去做其他配置,在AOP的默认配置属性中,spring.aop.auto属性默认是开启的,也就是说引入AOP依赖后,默认已经增加了@EnableAspectJAutoProxy。
2) 定义切面类需要两个类的注解:@Component注解把切面类加入到IOC容器中;@Aspect注解使之成为切面类。
3) 切面类中:@Pointcut定义切入点;
@Before在连接点之前执行;
@After:当某连接点退出时执行的通知(不论是正常返回还是异常退出)。;
@AfterReturning记录返回的对象;@AfterThrowing:在方法抛出异常退出时执行的通知。
    
二、总结
切点标志符号:
AspectJ5的切点表达式由标志符和操作参数组成,如“execution(public * com.aop.aop.controller..*.*(..))“的切点表达式,execution就是标志符号,而圆括号里的“public * com.aop.aop.controller..*.*(..)”就是操作参数。
execution
匹配 join point 的执行, 例如 "execution(* hello(..))" 表示匹配所有目标类中的 hello() 方法. 这个是最基本的 pointcut 标志符.
within
匹配特定包下的所有 join point, 例如 within(com.xys.*) 表示 com.xys 包中的所有连接点, 即包中的所有类的所有方法. 而 within(com.xys.service.*Service) 表示在 com.xys.service 包中所有以 Service 结尾的类的所有的连接点.
this 与 target
this 的作用是匹配一个 bean, 这个 bean(Spring AOP proxy) 是一个给定类型的实例(instance of). 而 target 匹配的是一个目标对象(target object, 即需要织入 advice 的原始的类), 此对象是一个给定类型的实例(instance of).
bean
匹配 bean 名字为指定值的 bean 下的所有方法, 例如:
bean(*Service) // 匹配名字后缀为 Service 的 bean 下的所有方法
bean(myService) // 匹配名字为 myService 的 bean 下的所有方法
args
匹配参数满足要求的的方法.
例如:
@Pointcut("within(com.xys.demo2.*)")
public void pointcut2() {
}
@Before(value = "pointcut2()  &&  args(name)")
public void doSomething(String name) {
    logger.info("---page: {}---", name);
}
@Service
public class NormalService {
    private Logger logger = LoggerFactory.getLogger(getClass());
    public void someMethod() {
        logger.info("---NormalService: someMethod invoked---");
    }
    public String test(String name) {
        logger.info("---NormalService: test invoked---");
        return "服务一切正常";
    }
}
当 NormalService.test 执行时, 则 advice doSomething 就会执行, test 方法的参数 name 就会传递到 doSomething 中.
常用例子:
// 匹配只有一个参数 name 的方法
@Before(value = "aspectMethod()  &&  args(name)")
public void doSomething(String name) {
}
// 匹配第一个参数为 name 的方法
@Before(value = "aspectMethod()  &&  args(name, ..)")
public void doSomething(String name) {
}
// 匹配第二个参数为 name 的方法
Before(value = "aspectMethod()  &&  args(*, name, ..)")
public void doSomething(String name) {
}
@annotation
匹配由指定注解所标注的方法, 例如:
@Pointcut("@annotation(com.xys.demo1.AuthChecker)")
public void pointcut() {
}
则匹配由注解 AuthChecker 所标注的方法.
常见的切点表达式
匹配方法签名
// 匹配指定包中的所有的方法
execution(* com.xys.service.*(..))
// 匹配当前包中的指定类的所有方法
execution(* UserService.*(..))
// 匹配指定包中的所有 public 方法
execution(public * com.xys.service.*(..))
// 匹配指定包中的所有 public 方法, 并且返回值是 int 类型的方法
execution(public int com.xys.service.*(..))
// 匹配指定包中的所有 public 方法, 并且第一个参数是 String, 返回值是 int 类型的方法
execution(public int com.xys.service.*(String name, ..))
匹配类型签名
// 匹配指定包中的所有的方法, 但不包括子包
within(com.xys.service.*)
// 匹配指定包中的所有的方法, 包括子包
within(com.xys.service..*)
// 匹配当前包中的指定类中的方法
within(UserService)
// 匹配一个接口的所有实现类中的实现的方法
within(UserDao+)
匹配 Bean 名字
// 匹配以指定名字结尾的 Bean 中的所有方法
bean(*Service)
切点表达式组合
// 匹配以 Service 或 ServiceImpl 结尾的 bean
bean(*Service || *ServiceImpl)
// 匹配名字以 Service 结尾, 并且在包 com.xys.service 中的 bean
bean(*Service) && within(com.xys.service.*)
”
三、来源
https://segmentfault.com/a/1190000007469968
https://www.cnblogs.com/lic309/p/4079194.html
https://blog.csdn.net/lmb55/article/details/82470388
Spring Boot 整合 AOP的更多相关文章
- Spring Boot2(六):使用Spring Boot整合AOP面向切面编程
		
一.前言 众所周知,spring最核心的两个功能是aop和ioc,即面向切面和控制反转.本文会讲一讲SpringBoot如何使用AOP实现面向切面的过程原理. 二.何为aop  aop全称Aspec ...
 - Spring Boot整合Mybatis并完成CRUD操作
		
MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作. 为什么要使用Mybatis?我们需要掌握Mybatis吗? 说的官 ...
 - Spring Boot整合Mybatis完成级联一对多CRUD操作
		
在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...
 - 太妙了!Spring boot 整合 Mybatis Druid,还能配置监控?
		
Spring boot 整合 Mybatis Druid并配置监控 添加依赖 <!--druid--> <dependency> <groupId>com.alib ...
 - Spring Boot 整合 Elasticsearch,实现 function score query 权重分查询
		
摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢! 『 预见未来最好的方式就是亲手创造未来 – <史蒂夫·乔布斯传> 』 运行环境: ...
 - spring boot整合jsp的那些坑(spring boot 学习笔记之三)
		
Spring Boot 整合 Jsp 步骤: 1.新建一个spring boot项目 2.修改pom文件 <dependency> <groupId>or ...
 - spring boot 系列之四:spring boot 整合JPA
		
上一篇我们讲了spring boot 整合JdbcTemplate来进行数据的持久化, 这篇我们来说下怎么通过spring boot 整合JPA来实现数据的持久化. 一.代码实现 修改pom,引入依赖 ...
 - Spring Kafka和Spring Boot整合实现消息发送与消费简单案例
		
本文主要分享下Spring Boot和Spring Kafka如何配置整合,实现发送和接收来自Spring Kafka的消息. 先前我已经分享了Kafka的基本介绍与集群环境搭建方法.关于Kafka的 ...
 - spring boot整合Hadoop
		
最近需要用spring boot + mybatis整合hadoop,其中也有碰到一些坑,记录下来方便后面的人少走些弯路. 背景呢是因为需要在 web 中上传文件到 hdfs ,所以需要在spring ...
 
随机推荐
- nagios配置邮件告警
			
1.编辑配置文件 vim /etc/nagios/objects/contacts.cfg增加如下内容:define contactgroup{ contactgroup_name admins al ...
 - Oracle自动性能统计
			
Oracle自动性能统计 高效诊断性能问题,需要提供完整可用的统计信息,好比医生给病人看病的望闻问切,才能够正确的确诊,然后再开出相应的药方.Oracle数据库为系统.会话以及单独的sql语句生成 ...
 - 什么是 go vendor
			
go vendor 是golang引入管理包依赖的方式,1.5版本开始引进,1.6正式引进. 基本原理其实就是将依赖的包,特指外部包,复制到当前工程下的vendor目录下,这样go build的时候, ...
 - vsftp新建用户及目录时遇到的坑
			
1.有关vsftp配置及用户权限设置,请参考: http://blog.sina.com.cn/s/blog_3edc5e2e0102vzv8.html 2.需求:公司另一部门要求单独建一目录,来存在 ...
 - CTF—攻防练习之ssh私钥泄露
			
攻防练习1 ssh私钥泄露 靶场镜像:链接: https://pan.baidu.com/s/1xfKILyIzELi_ZgUw4aXT7w 提取码: 59g0 首先安装打开靶场机 没办法登录,也没法 ...
 - cocos2dx[3.2](8) 数学类Vec2/Size/Rect
			
数学类Vec2.Size.Rect,是cocos2dx中比较常用的类. 比如设置图片位置,设置图片大小,两图片的碰撞检测等等. 比起2.x版本,在3.x中本质上其实没有太大的变化,主要的变化就是将全局 ...
 - tarjan缩点相关知识及代码
			
emmm原谅我确实是找不到不用缩点的tarjan题才会想到自学一下缩点这个东西的.. 题目没有,只能自己出数据并手动模拟... 首先看一张图(懒得画,还是看输入数据吧,劳烦自行画图..) 7 9(n个 ...
 - 【神经网络与深度学习】caffe+VS2013+Windows无GPU快速配置教程
			
首先来一波地址: happynear大神的第三方caffe:http://blog.csdn.net/happynear/article/details/45372231 Neil Z大神的第三方ca ...
 - 【Qt开发】Qt应用程序发布封装
			
问题:在使用Qt5.3.2编写程序并release,文件夹中已经添加了必要的dll,但在其他机子上运行程序失败,出现了下面的情况: 解决方法一:在C:\Qt\Qt5.3.2\5.3中进入mingw48 ...
 - 【洛谷p1781】宇宙总统
			
宇宙总统[题目链接] 关于题目算法,其实就是考排序,那我们直接sort不就好啦,显然不能. 这个题让我重新认识了cmp函数: 以下是我的心路历程: 看到这个题,嗯?这么简单的吗,我直接sort不就好啦 ...