• 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的实现类座位目标类,在切面类中使用环绕方法,获取参数,先从缓存获取,如果缓存有,就直接返回值,缓存没有就从数据库获取然后删除缓存。





     
  • 相关阅读:
    BZOJ1029:[JSOI2007]建筑抢修(贪心,堆)
    1054. [HAOI2008]移动玩具【BFS】
    1297. [SCOI2009]迷路【矩阵乘法】
    1192. [HNOI2006]鬼谷子的钱袋【进制】
    2243. [SDOI2011]染色【树链剖分】
    1051. [HAOI2006]受欢迎的牛【强连通分量】
    codevs 2074 营救 WW
    codevs 1191 数轴染色
    codevs 2855 游乐园的迷宫 bfs
    codevs 2806 红与黑
  • 原文地址:https://www.cnblogs.com/ghwq/p/13285076.html
Copyright © 2020-2023  润新知