java-spring aop

导读

  • AOP 面向切面编程 Aspect oriented Programming
  • OOP 面向对象编程 Object oriented Programming
  • 作用:在不惊动原始设计的基础上进行功能增强。
  • 切入点表达式可以是接口,也可以是实现类
    image
    image
    image
    image

1、导入坐标

<!-- aop面向切面 -->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.19</version>
	<scope>runtime</scope>
</dependency>

2、在SpringConfig上开启@EnableAspectJAutoProxy

@Configuration
@ComponentScan("cn.tjhis")
@PropertySource({"classpath:druid.properties"})
@Import({DbConfig.class,MybatisConfig.class})
@EnableAspectJAutoProxy
public class SpringConfig {
}

3、开发切面

  • 前提:只有在执行ProductInfoServicesave方法时,会触发。
@Component
@Aspect
public class MyAdvice {
    @Pointcut("execution(void cn.tjhis.service.ProductInfoService.save())")
    private void execute(){};
    @Before("execute()")
    public void method(){
        System.out.println(LocalDateTime.now());
    }
}

    // 任意返回值,任意包下 任意参数 以Service结尾的子类
    @Pointcut("execution(* *..*Service+.*(..))")
    private void execute(){};
    @Before("execute()")
    public void method(){
        System.out.println(LocalDateTime.now());
    }

image

  • 通过service.getClass()可以看到被代理的那个对象

切入点通知类型

@Component
@Aspect
public class MyAdvice {
    // 任意返回值,任意包下 任意参数 以Service结尾的子类
    @Pointcut("execution(* *..*Service+.save(..))")
    private void execute() {
    }

    ;

    /**
     * 前置通知
     */
    @Before("execute()")
    public void before() {
        System.out.println(LocalDateTime.now());
    }

    /**
     * 后置通知
     */
    @After("execute()")
    public void after() {
        System.out.println(LocalDateTime.now());
    }

    /**
     * 如果同时存在 执行顺序为 此方法before -> 前置通知  -> afterReturning  -> 后置通知 -> 此方法after
     *
     * @param joinPoint 切入点
     * @throws Throwable 异常
     */
    @Around("execute()")    
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
	   // 显示调用的类名和方法名
        Signature signature = joinPoint.getSignature();
        // 方法名
        String methodName = signature.getName();
        // 类
        Class<?> cls = signature.getDeclaringType();
        // 类名
        String className = signature.getDeclaringTypeName();
        System.out.println(className + " " + methodName );
        System.out.println("before:" + LocalDateTime.now());
        // 执行原始方法
        Object obj = joinPoint.proceed();
        System.out.println("after:" + LocalDateTime.now());
        return obj;
    }

    /**
     * 返回后
     */
    @AfterReturning("execute()")
    public void afterReturning() {
        System.out.println("afterReturning:" + LocalDateTime.now());
    }

    /**
     * 异常
     */
    @AfterThrowing("execute()")
    public void afterThrowing() {
        System.out.println("afterThrowing:" + LocalDateTime.now());
    }
}

Around 是重点

image
image

@Component
@Aspect
public class MyAdvice {
    // 任意返回值,任意包下 任意参数 以Service结尾的子类
    @Pointcut("execution(* *..*Service+.save(..))")
    private void execute() {
    }

    ;

    /**
     * 前置通知
     */
    @Before("execute()")
    public void before(JoinPoint point) {
        System.out.println("前置通知参数"+ Arrays.toString(point.getArgs()));
        System.out.println(LocalDateTime.now());
    }

    /**
     * 后置通知
     */
    @After("execute()")
    public void after() {
        System.out.println(LocalDateTime.now());
    }

    /**
     * 如果同时存在 执行顺序为 此方法before -> 前置通知  -> afterReturning  -> 后置通知 -> 此方法after
     * @param point 切入点
     * @throws Throwable 异常
     */
    @Around("execute()")
    public Object around(ProceedingJoinPoint point)  {
        System.out.println("环绕参数"+ Arrays.toString(point.getArgs()));
        // 显示调用的类名和方法名
        Signature signature = point.getSignature();
        // 方法名
        String methodName = signature.getName();
        // 类
        Class<?> cls = signature.getDeclaringType();
        // 类名
        String className = signature.getDeclaringTypeName();
        System.out.println(className + " " + methodName );
        System.out.println("before:" + LocalDateTime.now());
        // 执行原始方法
        Object obj = null;
        try {
            obj = point.proceed();
        } catch (Throwable e) {
            System.out.println(e.getMessage());
        }
        System.out.println("after:" + LocalDateTime.now());
        return obj;
    }

    /**
     * 返回后
     */
    @AfterReturning(value = "execute()",returning = "ret")
    public void afterReturning(Object ret) {
        System.out.println("afterReturning:" + LocalDateTime.now() + " 返回值:" + ret);
    }

    /**
     * 异常
     */
    @AfterThrowing(value = "execute()",throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("afterThrowing:" + LocalDateTime.now() + " 异常:" + e.getMessage());
    }
}
  • 若参数中含有空格,去除空格 记得参数修改后必须再传回去
@Around("execute()")
    public Object around(ProceedingJoinPoint point)  {
        Object[] args = point.getArgs();
        for (int i = 0; i < args.length; i++) {
            if (Objects.equals(args[i].getClass(),String.class)){
                args[i] = args[i].toString().trim();
            }
        }
        return point.proceed(args);
    }
posted @ 2023-03-05 14:17  his365  阅读(17)  评论(0编辑  收藏  举报