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





     
  • 相关阅读:
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    Java实现 LeetCode 792 自定义字符串排序(暴力)
    asp.net session对象的持久化
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 791 自定义字符串排序(桶排序)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    Java实现 LeetCode 790 多米诺和托米诺平铺(递推)
    小白也能看懂的约瑟夫环问题
  • 原文地址:https://www.cnblogs.com/ghwq/p/13285076.html
Copyright © 2011-2022 走看看