SpringBoot中AOP开发

spring中的AOP即面向切面编程:它是在不改变源代码的前提下,对类中的方法进行增强,分为前置,后置,环绕,异常,全篇分为三个方面,aop开发基础讲解,切面类的传参和值的返回,以及使用aop做缓存的一些思路

切面基础讲解

创建项目前:引入aop

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

 

创建Person:
@Component
public class Person {
    public void eat(){
        System.out.println("我要开始吃饭了");
    }
}

创建切面类:
  第一个:前置增强:注意声明切面位置指定是类中的方法
@Component
@Aspect
@EnableAspectJAutoProxy
public class PersonAspect {
        
private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; @Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } }


  第二个:增加后置增强
@Component
@Aspect
@EnableAspectJAutoProxy
public class PersonAspect {
    private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))";

    @Before(PERSON_POINT)
    public void before(){
        System.out.println("请先喝汤");
    }
     @After(PERSON_POINT)
    public void after(){
        System.out.println("睡觉了");
    }
}

  第三个:环绕增强
@Component
@Aspect
@EnableAspectJAutoProxy
public class PersonAspect {
    private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))";

    //@Before(PERSON_POINT)
    public void before(){
        System.out.println("请先喝汤");
    }
    // @After(PERSON_POINT)
    public void after(){
        System.out.println("睡觉了");
    }
    @Around(PERSON_POINT)
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        before();
        joinPoint.proceed();
        after();
    }
}

  第四个:异常
    先在被切面的类上设置异常
@Component
public class Person {
    public void eat(){
        System.out.println("我要开始吃饭了");
        int num = 10/0;
    }
}

      在切面类中捕获异常

@Component
@Aspect
@EnableAspectJAutoProxy
public class PersonAspect {
    private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))";

    //@Before(PERSON_POINT)
    public void before(){
        System.out.println("请先喝汤");
    }
    // @After(PERSON_POINT)
    public void after(){
        System.out.println("睡觉了");
    }
    @Around(PERSON_POINT)
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        before();
        joinPoint.proceed();
        after();
    }

    //throwing = "aw" 和Throwable aw 俩个变量名要保持一致
    @AfterThrowing(value =PERSON_POINT,throwing = "aw")
    public void exc(Throwable aw){
        System.out.println("出错信息"+aw.getMessage());
    }
}

 




测试:
  前置增强测试
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTest {

    @Autowired
    private Person person;
    @Test
    public void aopTest(){
        person.eat();
    }
}

  结果:在执行自身方法,被拦截,先执行切面类中的方法
后置增强测试类同上,结果:

 


  环绕增强测试结果

 

 

 异常测试展示:

 

 

 

在执行类中的方法时,在切面中返回方法返回值

问题出现:在类中方法设置返回值
@Component
public class Person {
    public String eat(){
        System.out.println("我要开始吃饭了");
       return "吃肉了";
    }
}

增强类

@Component
@Aspect
@EnableAspectJAutoProxy
public class PersonAspect {
    private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))";

    //@Before(PERSON_POINT)
    public void before(){
        System.out.println("请先喝汤");
    }
    // @After(PERSON_POINT)
    public void after(){
        System.out.println("睡觉了");
    }
    @Around(PERSON_POINT)
    public void around(ProceedingJoinPoint joinPoint) throws Throwable {
        before();
        joinPoint.proceed();
        after();
    }
}

测试类调用:输出方法中的值

@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTest {
    @Autowired
    private Person person;
    @Test
    public void aopTest(){
        String food = person.eat();
        System.out.println(food);
    }
}

 

 

问题解决:输出类中的返回值
    对上面的切面做修改
 @Around(PERSON_POINT)
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        before();
        Object proceed = joinPoint.proceed();
        after();
        return proceed;
    }

查看测试结果:

 

 

 在切面类中,获取执行类的方法参数

 

在执行类中添加参数

 

 

 

在切面类获取参数

 

 

 

测试结果

 

 

输出了鸡肉,说明获取了参数返回值

使用Spring AOP来实现缓存的使用:逻辑是在以setvice的实现类座位目标类,在切面类中使用环绕方法,获取参数,先从缓存获取,如果缓存有,就直接返回值,缓存没有就从数据库获取然后删除缓存。



 



 
posted @ 2020-07-11 19:12  西以北偏北  阅读(308)  评论(0编辑  收藏  举报