1. 相关注解介绍

1.1 放在配置类上的注解

@EnableAspectJAutoProxy 用于开启spring对注解aop的支持

1.2 放在增强方法的类上(里)的注解

@Aspect 位置放到aspect类上面,表示这个是一个aspect
Pointcut 在aspect类里面添加一个函数,在函数上面添加该注解,用于配置一个切入点
具体pointcut表达式的编写可以参考spring aop|切入点pointcut表达式编写方案示例

1.2.1 用于配置通知的

1.2.1.1 @Before
  • 作用:被此注解修饰的方法为前置通知。前置通知的执行时间点是在切入点方法执行之前。
  • 使用场景:
  • 在实际开发中,我们需要对切入点方法执行之前进行增强, 此时就用到了前置通知。
  • 在通知(增强的方法)中需要获取切入点方法中的参数进行处理时,就要配合切入点表达式参数来使用。
1.2.1.2 @AfterReturning
  • 作用:用于配置后置通知。后置通知的执行是在切入点方法正常执行之后执行。
    需要注意的是,由于基于注解的配置时,spring创建通知方法的拦截器链时,后置通知在最终通知之后,所以会先执行@After注解修饰的方法。
  • 使用场景:
    此注解是用于配置后置增强切入点方法的。被此注解修饰方法会在切入点方法正常执行之后执行。
    在我们实际开发中,像提交事务,记录访问日志,统计方法执行效率等等都可以利用后置通知实现。
1.2.1.3 @AfterThrowing
  • 作用:用于配置异常通知。
  • 使用场景:用此注解修饰的方法执行时机是在切入点方法执行产生异常之后执行。
1.2.1.4 @After
  • 作用:用于指定最终通知。
  • 使用场景:
    最终通知是在切入点方法执行完成之后执行,无论切入点方法执行是否产生异常最终通知都会执行。
    所以被此注解修饰的方法,通常都是做一些清理操作。
1.2.1.5 @Around
  • 作用:用于指定环绕通知。
  • 使用场景:
    环绕通知有别于前面介绍的四种通知类型。
    它是spring为我们提供的一种可以通过编码的方式手动控制增强方法何时执行的机制。

2. example

aspect文件:用于增强

@Component
@Aspect
public class MyLogAspect {

    @Pointcut("execution(* com..*.*(..))")
    private void pointcut(){}

    @Before("pointcut()")
    public void logBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println("[logBefore]");
    }

    @AfterReturning("pointcut()")
    public void logAfterReturn(JoinPoint joinPoint) throws Throwable {
        System.out.println("[logAfterReturn]");
    }

    @AfterThrowing("pointcut()")
    public void logAfterThrowException(JoinPoint joinPoint) throws Throwable {
        System.out.println("[logAfterThrowException]");
    }

    @After("pointcut()")
    public void logAfter(JoinPoint joinPoint) throws Throwable {
        System.out.println("[logAfter]");
    }
}

pojo文件:用于被增强

@Component
public class Student {
    public void speak(){
        System.out.println("i love Java!");
//        throw new RuntimeException("123456");
    }
}

配置类

@Configuration
@ComponentScan("com.kehao")
@EnableAspectJAutoProxy
public class ApplicationContext {
}

测试代码

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {ApplicationContext.class})
public class StudentTest {
    @Autowired
    private Student student;

    @Test
    public void speak() {
        student.speak();
    }
}

详细代码:https://github.com/chenkehao1998/JavaExampleForBlog/tree/main/spring_aop_anno