springboot笔记09——使用aop

什么是AOP?

aop(Aspect Oriented Programming)面向切面编程,是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。但是在为分散的对象引入公共行为的时候,OOP显得无能为力。OOP擅长从上到下的关系,但是不适合从左到右的关系,例如日志、权限,这些功能的代码往往是水平地分布在对象层次中,而与所在的对象的核心功能关系不大。这些代码称为“横切”代码,在OOP中,这导致了大量的代码冗余,且不利于模块间代码的重用。

AOP则擅长于切面编程,将那些影响多个类的公共行为封装到一个模块中,供其他模块重用,便于减少重复代码,降低模块间的耦合度,提高系统的可操作性和可维护性。

一些关于aop的术语

  • Aspect: 切面,包含一些Pointcut和Advice
  • Pointcut:切入点,相当于一个条件,只有符合条件的方法才会走Advice
  • advice:通知,只有符合Pointcut的方法会执行通知,advice分为before,around,after,AfterReturning,AfterThrowing
  • advice通过以下几种通知来确定在什么时候调用advice
    • @before:前置通知,方法执行之前调用advice
    • @around:环绕通知,方法执行前后都会调用advice
    • @after:后置通知,方法执行之后调用advice(无论方法执行是否发送异常,总是调用)
    • @AfterReturning:后置通知,方法执行之后调用advice,可以获取返回值 (无论方法执行是否发送异常,总是调用)
    • @AfterThrowing:后置通知,方法执行中发生异常后调用,可以获取异常信息(只有发生异常才会)

springboot使用aop

创建项目,引入依赖

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


Aspect配置类

@Aspect
@Component
public class MyAspect {
    /*
    * 切入点
    * */
    @Pointcut("execution(public * com.jotal.springboot07aop.controller.*.*(..))")
    public void execute() {

    }

    /*
     * 前置通知
     * */
    @Before(value = "execute()")
    public void Before(JoinPoint joinPoint) {
        System.out.println("执行方法之前!");
    }

    /*
    * 环绕通知
    * */
    @Around(value = "execute()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("环绕通知开始");
        try {
            System.out.println("执行方法:"+proceedingJoinPoint.getSignature().getName());
            Object Object = proceedingJoinPoint.proceed();
            System.out.println("环绕结束,方法返回:"+Object);
            return Object;
        } catch (Throwable e) {
            System.out.println("执行方法异常:"+e.getClass().getName());
            return null;
        }
    }

    /*
    * 后置通知
    * */
    @After(value = "execute()")
    public void after(){
        System.out.println("执行方法之后!");
    }

    /*
    * 后置通知,带有返回值
    * */
    @AfterReturning(pointcut = "execute()",returning = "obj")
    public void afterReturn(Object obj){
        System.out.println("执行方法后获取返回值:" + obj);
    }

    /*
    * 后置通知,异常时执行
    * */
    @AfterThrowing(throwing = "e",pointcut = "execute()")
    public void doAfterThrowing(Exception e){
        System.out.println("执行方法异常:" + e.getClass().getName());
    }
}

@Aspect :标注切面类

@Component:注入spring ioc容器管理

@Pointcut("execution(public * com.jotal.springboot07aop.controller.*.*(..))"):声明切入点

"execution(public * com.jotal.springboot07aop.controller.*.*(..))":条件表达式, com.jotal.springboot07aop.controller包下的public声明的方法都会使用aop

@Before,@Around,@After,@AfterReturning,@AfterThrowing:通知类型


控制类

@RestController
public class testController {

    @GetMapping("/useAop")
    public String useAop(){
        return "方法的返回";
    }

    @GetMapping("/doNotUseAop")
    void doNotUseAop(){
         System.out.println("doNotUseAop");
    }

    @GetMapping("/throw")
    public void throwException(){
        throw new RuntimeException();
    }
}


测试

有通知

http://localhost:8080/doNotUseAop


无通知

http://localhost:8080/useAop


抛出异常

http://localhost:8080/throw

猜你喜欢

转载自www.cnblogs.com/Jotal/p/11323479.html