Hello World

Spring boot aop

1. mavne依赖

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

2.Aop

2.1 Aspect

在spring中,在类上添加 @Aspect 注解,即表示这是一个切面类

  @Aspect
  @Component
  public class HelloAspectj {
  }

2.2 Pointcut

切点,定义在哪些地方进行功能增强

	/**
	 * 通过 execution 表达式定义切点
	 */
	@Pointcut("execution(* com.example.demo.aop..*.*(..))")
	public void helloPointcut(){}

	/**
	 * 通过注解定义切点,对方法上添加该注解的方法进行增强
	 */
	@Pointcut("@annotation(com.example.demo.aop.func.service.LogAspect)")
	public void helloPointcutAnnotation(){}

2.2.1 execution

execution表达式定义切点, * com.example.demo.aop..*.*(..)

  • 第一个* 方法的返回值类型
  • com.example.demo.aop 应用aop的package
  • .. 当前包及子包
  • * 类名,* 表示所有类
  • * 方法名,*表示所有方法
  • (..) 参数类型, ..表示所有参数类型

2.2.2 annotation

通过注解定义切点,对添加指定注解的方法进行功能增强

2.3 Advice

通知,定义功能增强的时机和内容
切面类

package com.example.demo.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class HelloAspectj {

	//	@Before("execution(* com.example.demo.aop.func.service.IHello.hello(..))")
	@Pointcut("execution(* com.example.demo.aop..*.*(..))")
	public void helloPointcut(){}

	/**
	 * @param joinPoint	连接点信息,可获取到方法的元数据信息及参数信息
	 */
	@Before("helloPointcut()")
	public void Before(JoinPoint joinPoint) {
		System.out.println("Before");
	}

	/**
	 * @param joinPoint	连接点信息,可获取到方法的元数据信息及参数信息
	 */
	@After("helloPointcut()")
	public void After(JoinPoint joinPoint) {
		System.out.println("After");
	}

	/**
	 * 如果方法有返回值,则此方法必须定义返回值,否则
	 */
	@Around("helloPointcut()")
	public Object Around(ProceedingJoinPoint joinPoint) {
		System.out.println("Around");
		Object proceed = null;
		try {
			// 调用目标方法并获得方法返回值
			proceed = joinPoint.proceed();
		} catch (Throwable throwable) {
			throwable.printStackTrace();
		}
		return proceed;
	}

	/**
	 * @param joinPoint	连接点信息
	 * @param value		返回值
	 */
	@AfterReturning(pointcut = "helloPointcut()",returning = "value")
	public void AfterReturning(JoinPoint joinPoint,Object value) {
		System.out.println("AfterReturning value " + value);
	}

	/**
	 * @param joinPoint 连接点信息
	 * @param ex		异常信息
	 */
	@AfterThrowing(pointcut = "helloPointcut()",throwing = "ex")
	public void AfterThrowing(JoinPoint joinPoint,Throwable ex) {
		System.out.println("AfterThrowing");
	}
}

2.3.1 时机

如果目标方法在所有时机都进行方法增强,则按照下面的顺序执行增强方法
AfterReturnning 和 AfterThrowing为互斥项,一次调用中只能有一个生效

  • @Around 环绕通知:方法执行前添加逻辑处理,然后手动调用目标方法,(ProceedingJoinPoint.proceed()),然后在方法执行后进行逻辑处理
  • @Before 前置通知:方法执行之前
  • @AfterReturnning 返回通知:方法成功执行之后通知,
  • @AfterThrowing 异常通知:抛出异常之后通知
  • @After 后置通知:方法执行之后

2.3.2 内容

增强的内容即是该通知对应的具体方法

2.3.3 内部调用

切点对某个类中的所有方法进行增强,其中该类中的方法methodA调用的该类中的方法methodB,此时methodB不会被增强
这种情况若需要对methodB进行增强,则在methodA中按照下面方式调用methodB

CurrentClass proxy =(CurrentClass) AopContext.currentProxy();
proxy.menthodB();
posted @ 2021-09-23 19:03  小小忧愁米粒大  阅读(82)  评论(0编辑  收藏  举报
瞅啥瞅,好好看书