美文网首页
spring boot:AOP

spring boot:AOP

作者: 远方的橄榄树 | 来源:发表于2019-11-20 14:42 被阅读0次

    1、简介

    • AOP即面向切面编程Aspect Oriented Program
    • 面向切面编程将系统功能分为核心业务功能切面功能,核心业务功能主要是注册登录、数据库操作等,切面功能主要有日志、权限、性能分析等。
    • AOP将与核心功能一起调用的任务和逻辑分离开并封装起来,有助于减少系统的重复代码,降低模块间的耦合度。

    2、AOP中的概念

    • 切点(PointCut):指定切入的类或方法(\color{red}{where}
    • 通知(Advice):对方法在什么时间(\color{red}{when})需要执行的操作(\color{red}{what}
    • 切面(Aspect):切点+通知
    • 织入(Weaving):将切面加入到对象中,并创建代理的过程。

    3、AOP的通知类型

    • before(前置通知):在方法开始执行前执行
    • after(后置通知): 在方法执行后执行
    • afterReturning(返回后通知): 在方法返回后执行
    • afterThrowing(异常通知): 在抛出异常时执行
    • around(环绕通知): 在方法执行前和执行后都会执行

    4、快速入门

    • 构建spring boot项目
    • 引入AOP依赖
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
            </dependency>
    
    • 创建一个service类
    public class Calculator {
    
        public int divide(int a, int b) {
            System.out.println("除法:" + a + "/" + b);
            return a / b;
        }
    
        public int add(int a, int b) {
            System.out.println("加法:" + a + "+" + b);
            return a + b;
        }
    }
    
    • 编写切面类
    @Aspect
    public class CalculatorAop {
    
        //切点 Calculator的+-*/方法
        @Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.divide(..))")
        public void pointCut() {}
    
        @Before("pointCut()")
        public void before(JoinPoint joinPoint) {
            System.out.println("Before...");
            Signature signature = joinPoint.getSignature(); // 获取方法的签名
            System.out.println("执行运算:" + signature.getName()); // 获取方法名称
            System.out.println("执行参数:" + Arrays.toString(joinPoint.getArgs())); // 方法参数
        }
    
        @After("pointCut()")
        public void after() {
            System.out.println("After...");
        }
    
        @AfterReturning(value = "pointCut()", returning = "result")
        public void afterReturning(Object result) {
            System.out.println("Returning...");
            System.out.println("执行结果:" + result);
        }
    
        @AfterThrowing(value = "pointCut()", throwing = "exception")
        public void afterThrowing(Exception exception) {
            System.out.println("Throwing...");
            System.out.println(exception.getMessage());
        }
    }
    
    • 编写配置类
    @Configuration
    @EnableAspectJAutoProxy // 开启aop
    public class CalculatorConfig {
    
        @Bean // 注入计算器
        public Calculator calculator() {
            return new Calculator();
        }
    
        @Bean // 注入aop
        public CalculatorAop calculatorAop() {
            return new CalculatorAop();
        }
    }
    
    • 测试
    class AopDemoApplicationTests {
    
        @Test
        public void divideTest() {
            AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(CalculatorConfig.class);
            // 注意只有注入容器的bean AOP才会生效
            Calculator calculator = context.getBean(Calculator.class);
    //        calculator.divide(13, 0);  // throwing... /By Zero
            calculator.divide(13, 2);
        }
    }
    
    Before...
    执行运算:divide
    执行参数:[13, 2]
    除法:13/2
    After...
    Returning...
    执行结果:6
    
    • 环绕通知(Around)可以用来替换以上四种通知
      CalculatorAop.class添加以下代码
        private static final Logger log = LoggerFactory.getLogger(CalculatorAop.class);
    
        @Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.add(..))")
        public void addPointCut() {}
    
        @Around("addPointCut()")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            try {
                System.out.println("around begin...");
                Object o = joinPoint.proceed(); // 执行目标方法
                System.out.println("around end...");
                return o;
            } catch (Throwable e) {
                System.out.println("around throwing...");
                log.error(e.getMessage());
                throw e;
            } finally {
                System.out.println("around returning...");
            }
        }
    
    • 测试
        @Test
        public void addTest() {
            AnnotationConfigApplicationContext context =
                    new AnnotationConfigApplicationContext(CalculatorConfig.class);
            Calculator calculator = context.getBean(Calculator.class);
            calculator.add(13, 0);
        }
    
    around begin...
    加法:13+0
    around end...
    around returning...
    

    相关文章

      网友评论

          本文标题:spring boot:AOP

          本文链接:https://www.haomeiwen.com/subject/uobnictx.html