spring 中aop 切面实战
切面相关注解:
@Aspect : 声明该类为一个注解类
@Pointcut : 定义一个切点
@Before : 在切点之前执行
@After : 在切点之后执行 不管目标方法是否执行成功
@AfterReturning : 切点返回内容后执行代码,可以对切点的返回值进行封装
@AfterThrowing : 切点抛出异常后执行
@Around : 环绕,在切点前后执行代
1.自定义注解:
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface timingAnnotation {
}
2.切面类
@Aspect
@Component
@Slf4j
public class AspectDemo { @Pointcut("@annotation(com.wl.demo.demos.aop.timingAnnotation)")
public void pointCut() {
} @Before("pointCut()")
public void doBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
log.info("IP: {}", request.getRemoteAddr());
log.info("URL: {}", request.getRequestURL().toString());
log.info("HTTP Method: {}", request.getMethod());
log.info("Class Method: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
} @Around("pointCut()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Object proceed = proceedingJoinPoint.proceed();
long endTime = System.currentTimeMillis();
log.info("[方法耗时]" + methodSignature.getDeclaringTypeName() + "." + methodSignature.getMethod().getName() + " 耗时: " + (endTime - startTime) + "毫秒");
return proceed;
} @After("pointCut()")
public void doAfter(JoinPoint joinPoint) {
log.info("目标方法执行完之后执行");
} @AfterThrowing(pointcut = "pointCut()", throwing = "e")
public void doAfterThrow(JoinPoint joinPoint, RuntimeException e) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
log.info("HTTP Method: {}", request.getMethod());
log.info("Class Method: {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
} }
注:引入aspect 需要引入jar:
<!--引入aop aspectj-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
spring 中aop 切面实战的更多相关文章
- Spring 中aop切面注解实现
spring中aop的注解实现方式简单实例 上篇中我们讲到spring的xml实现,这里我们讲讲使用注解如何实现aop呢.前面已经讲过aop的简单理解了,这里就不在赘述了. 注解方式实现aop我们 ...
- Spring中AOP切面编程学习笔记
注解方式实现aop我们主要分为如下几个步骤: 1.在切面类(为切点服务的类)前用@Aspect注释修饰,声明为一个切面类. 2.用@Pointcut注释声明一个切点,目的是为了告诉切面,谁是它的服务对 ...
- Spring AOP——Spring 中面向切面编程
前面两篇文章记录了 Spring IOC 的相关知识,本文记录 Spring 中的另一特性 AOP 相关知识. 部分参考资料: <Spring实战(第4版)> <轻量级 JavaEE ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- Spring中AOP原理,源码学习笔记
一.AOP(面向切面编程):通过预编译和运行期动态代理的方式在不改变代码的情况下给程序动态的添加一些功能.利用AOP可以对应用程序的各个部分进行隔离,在Spring中AOP主要用来分离业务逻辑和系统级 ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
- Spring中AOP相关源码解析
前言 在Spring中AOP是我们使用的非常频繁的一个特性.通过AOP我们可以补足一些面向对象编程中不足或难以实现的部分. AOP 前置理论 首先在学习源码之前我们需要了解关于AOP的相关概念如切点切 ...
- AOP 与 Spring中AOP使用(上)
AOP简介 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程, 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. AOP是OOP的延续 ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
随机推荐
- IDEA中,已经被加到版本库的文件如何在提交的时候忽略它们
因为某些资源共享的原因,我在本地调试的时候需要修改Java启动程序类上的一些配置,禁用掉Kafka等等.然后我就想 把这些本地调试需要修改的但是线上服务不需要修改的给忽略掉,于是加入到了.gitign ...
- Java源码详解系列(十一)--Spring的使用和源码
Spring 是一个一站式的 Java 框架,致力于提高我们项目开发的效率.通过 Spring,我们可以避免编写大量额外代码,更专注于我们的核心逻辑.目前,Spring 已经成为最受欢迎的 Java ...
- SolrCloud搭建
什么是SolrCloud? SolrCloud是基于 solr 和 zookeeper 的分布式搜索方案,它的主要思想是使用zookeeper作为SolrCloud集群的配置信息中心,统一管理Solr ...
- 要是想让程序跳转到绝对地址是0x100000去执行
要对绝对地址0x100000赋值,我们可以用 (unsigned int*)0x100000 = 1234; 那么要是想让程序跳转到绝对地址是0x100000去执行,应该怎么做? *((void (* ...
- 用IPV6隧道连接IPV4孤岛
hostA和hostB之间是IPV6连接的,但是之前的服务只能支持IPV4,兼容IPV6比较困难.所以用隧道实现hostA和hostB之间用IPV4连接. hostA如下: ip -6 addr ad ...
- Python数据类型--元组(tuple)
元组与列表非常相似,最大区别在于: (1)元组是不可修改的,定义之后就"固定"了. (2)元组在形式上是用()这样的圆括号括起来 (3)元组不能插入或删除元素 注:元素可修改与不可 ...
- java怎么产生随机数
随机数的产生在一些代码中很常用,也是我们必须要掌握的.而java中产生随机数的方法主要有三种: 第一种:new Random() 需要借助java.util.Random类来产生一个随机数发生器,也是 ...
- 正式班D9
2020.10.16星期五 正式班D9 一.vmware workstation的使用 虚拟机管理软件 定义 虚拟机(Virtual Machine)软件是一套特殊的软件,它可以作为操作系统独立运行, ...
- Navicat Premium_11.2.7简体中文版 破解版本 windows版本 失效
亲测可用 自己一直在用的 https://pan.baidu.com/s/1VVKKQoIKVB0BgNXBK4YTrQ
- C++switch结构