前言

Github:https://github.com/HealerJean

博客:http://blog.healerjean.com

1、Aspect

1.1、pom依赖

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

1.2、Service

1.2.1、接口 DemoEntityService

package com.healerjean.proj.service;

import com.healerjean.proj.dto.Demo.DemoDTO;

public interface DemoEntityService {

    DemoDTO getMmethod(DemoDTO demoEntity);

}

1.2.2、DemoEntityServiceImpl

@Service
@Slf4j
public class DemoEntityServiceImpl implements DemoEntityService {

    @Override
    public DemoDTO getMmethod(DemoDTO demoEntity) {
        log.info("Service--------getMmethod");
        // int i = 1/0;
        return demoEntity;
    }

}

1.3、Aspect

package com.healerjean.proj.config.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect //当前类标识为一个切面供容器读取  ,、@Aspect放在类头上,把这个类作为一个切面。
@Order(2) // 控制多个Aspect的执行顺序,越小越先执行
@Slf4j
public class AspectStyleMethod {

    /**
     * @Pointcut 放在方法头上,定义一个可被别的方法引用的切入点表达式
     */
    @Pointcut("execution(* com.healerjean.proj.service.*Service.*(..))")
    private void anyMethod() {
    }

    /**
     * @Before 标识一个前置增强方法
     */
    @Before("anyMethod()")
    public void before() {
        log.info("@Before");
    }

    /**
     * @After: final增强,不管是抛出异常或者正常退出都会执行
     */
    @After("anyMethod()")
    public void after() {
        log.info("@After");
    }

    /**
     * @AfterReturning :后置增强,方法正常退出时执行(有了异常就不会执行)
     */
    @AfterReturning("anyMethod()")
    public void afterReturning() {
        log.info("@AfterReturning");
    }


    /**
     * @AfterThrowing: 异常抛出增强,(有了异常才会执行,否则不能够执行(在around异常处理之前执行))
     */
    @AfterThrowing("anyMethod()")
    public void afterThrowing() {
        log.info(" @AfterThrowing");
    }


    /**
     * 正常调用
     * @Around: 环绕增强
     */
    @Around("anyMethod()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        log.info("@Around pjp.proceed() 准备执行");
        Object object = pjp.proceed();
        //下面的log.info不会执行,因为AspectStyleService中有了异常,所以不会到这一步
        log.info("@Around   pjp.proceed() 执行完毕");
        return object;
    }

}

1.3.1、正常调用

@Before@After 是在方法pjp.proceed()执行的前后

@Around pjp.proceed() 准备执行 com
@Before
Service--------getMmethod com.
@Around   pjp.proceed() 执行完毕
@After
@AfterReturning 

1.3.2、异常不捕获

@Around pjp.proceed() 准备执行 
@Before 
Service--------getMmethod 
@After 
@AfterThrowing 

1.3.3、异常捕获

@Around先捕获异常,然后才执行@After@AfterThrowing

/**
* 异常捕获
* @Around: 环绕增强
*/
@Around("anyMethod()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
    log.info("@Around   pjp.proceed() 准备执行");
    try {
        Object object = pjp.proceed();
        //下面的log.info不会执行,因为AspectStyleService中有了异常,所以不会到这一步
        log.info("@Around   pjp.proceed() 正常执行完毕");
        return object;
    } catch (Exception e) {
        log.info("@Around   pjp.proceed() 出错:{}", e.getMessage());
        throw e;
    }
}
@Around   pjp.proceed() 准备执行 
@Before
Service--------getMmethod 
@Around   pjp.proceed() 出错:/ by zero 
@After 
@AfterThrowing 

1.4、@Pointcut

​ @Pointcut(“execution(* com.healerjean.proj.service.Service.(..))”)

*  匹配任意字符,但只能匹配一个元素
.. 匹配任意字符,可以匹配任意多个元素,表示类时,必须和*联合使用
+  必须跟在类名后面,如Horseman+,表示类本身和继承或扩展指定类的所有类




1、execution(public * * (. .)) 任意公共方法被执行时,执行切入点函数。 
2、execution( * set* (. .)) 任何以一个“set”开始的方法被执行时,执行切入点函数。 
3、execution( * com.demo.service.AccountService.* (. .)) 当接口AccountService 中的任意方法被执行时,执行切入点函数。 
4、execution( * com.demo.service.. (. .)) 当service 包中的任意方法被执行时,执行切入点函数。 



多个切点
@Around("execution(* com.fintech.manager.controller.*.*Controller.*(..))" +
            "|| execution(* com.fintech.manager.task.*Task.*(..))")
            

ContactAuthor