zoukankan      html  css  js  c++  java
  • Spring-AOP的五种通知方式

    AOP的五种通知方式:

    前置通知:在我们执行目标方法之前运行(@Before

    后置通知:在我们目标方法运行结束之后,不管有没有异常(@After

    返回通知:在我们的目标方法正常返回值后运行(@AfterReturning

    异常通知:在我们的目标方法出现异常后运行(@AfterThrowing

    环绕通知:目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,joinPoint.procced()就是执行目标方法的代码 。环绕通知可以控制返回对象(@Around)

    一、导jar包

    com.springsource.net.sf.cglib-2.2.0.jar
    com.springsource.org.aopalliance-1.0.0.jar
    com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
    commons-logging-1.1.3.jar
    spring-aop-4.0.0.RELEASE.jar
    spring-aspects-4.0.0.RELEASE.jar
    spring-beans-4.0.0.RELEASE.jar
    spring-context-4.0.0.RELEASE.jar
    spring-core-4.0.0.RELEASE.jar
    spring-expression-4.0.0.RELEASE.jar
    spring-jdbc-4.0.0.RELEASE.jar
    spring-orm-4.0.0.RELEASE.jar
    spring-tx-4.0.0.RELEASE.jar
    spring-web-4.0.0.RELEASE.jar
    spring-webmvc-4.0.0.RELEASE.jar

    二、在类路径下建applicationContext.xml配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xmlns:context="http://www.springframework.org/schema/context"
    
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <!--配置自动扫描的包-->
        <context:component-scan base-package="com.atguigu.spring.aop"></context:component-scan>
    
        <!--配置自动为匹配aspectJ 注解的Java类生成代理对象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
    </beans>

    三、接口

    //接口
    public interface ArithmeticCalculator {
    
        int add(int i, int j);
    
        int sub(int i, int j);
    
        int mul(int i, int j);
    
        int div(int i, int j);
    }

    四、实现类

    package com.atguigu.spring.aop;
    
    import org.springframework.stereotype.Component;
    
    /**
     * @Author 谢军帅
     * @Date2019/12/6 21:23
     * @Description
     */
    
    //实现类
    @Component("arithmeticCalculator")
    public class ArithmeticCalculatorImpl implements ArithmeticCalculator {
        @Override
        public int add(int i, int j) {
            int relust = i+j;
            return relust;
        }
    
        @Override
        public int sub(int i, int j) {
            int relust = i-j;
            return relust;
        }
    
        @Override
        public int mul(int i, int j) {
            int relust = i*j;
            return relust;
        }
    
        @Override
        public int div(int i, int j) {
            int relust = i/j;
            return relust;
        }
    }

    五、定义切面类

    package com.atguigu.spring.aop;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    
    /**
     * @Author 谢军帅
     * @Date2019/12/11 11:17
     * @Description
     */
    @Component
    @Aspect
    public class LoggingAspect {
        /**
         * 在每一个接口的实现类的每一个方法开始之前执行一段代码
         */
    
        @Before("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.* (..))")
        public void beforeMethod(JoinPoint joinPoint){
            String methodName = joinPoint.getSignature().getName();
            Object[] args = joinPoint.getArgs();
    
            System.out.println("The method "+methodName+" begins with "+ Arrays.asList(args));
        }
    
        @After("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.* (..))")
        public void afterMethod(JoinPoint joinPoint){
            String methodName = joinPoint.getSignature().getName();
    
            System.out.println("The method "+methodName +" end......");
        }
    
    
        /**
         * 返回通知
         * 在方法正常结束后执行的代码
         * 返回通知是可以访问方法的返回值的!
         * @param joinPoint*/
         
        @AfterReturning(value = "execution(public int com.atguigu.spring.aop.ArithmeticCalculator.* (..))",
                        returning = "result")
        public void afterReturning(JoinPoint joinPoint,Object result){
            String methodName = joinPoint.getSignature().getName();
            System.out.println("The method "+methodName +" end......result:"+result);
        }
    
    
        /**
         * 在目标方法出现异常时会执行的代码
         * 可以访问到异常对象,且可以指定在出现特定异常时在执行通知代码
         * @param joinPoint
         * @param ex*/
         
        @AfterThrowing(value = "execution(public int com.atguigu.spring.aop.ArithmeticCalculator.* (..))", throwing = "ex")
        public void afterThrowing(JoinPoint joinPoint, Exception ex){
            String methodName = joinPoint.getSignature().getName();
            System.out.println("The method "+methodName +"occurs exception :" +ex);
        }
    
        /**
         * 环绕通知需要携带 ProceedingJoinPoint 类型的参数
         * 环绕通知类似于动态代理的全过程:ProceedingJoinPoint 类型的参数可以决定是否执行目标方法。
         * 且环绕通知必须有返回值,返回值即为目标方法的返回值
         * @param proceedingJoinPoint
         */
        /*@Around("execution(public int com.atguigu.spring.aop.ArithmeticCalculator.* (..))")
        public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint){
    
            Object result = null;
            String methodName = proceedingJoinPoint.getSignature().getName();
    
            try {
                //前置通知
                System.out.println("The method "+methodName+" begins with "+Arrays.asList(proceedingJoinPoint.getArgs()));
                //执行目标方法
                result = proceedingJoinPoint.proceed();
    
                //返回通知
                System.out.println("The method ends with "+result);
            } catch (Throwable e) {
                //异常通知
                System.out.println("The method occurs exception:"+e);
    
                throw new RuntimeException(e);
            }
    
            //后置通知
            System.out.println("The method "+methodName+" ends........");
    
            return result;
        }*/
    }

    六、测试

    public class Test_aop {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    
            ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) context.getBean("arithmeticCalculator");
    
            System.out.println(arithmeticCalculator.getClass().getName());
    
            int result = arithmeticCalculator.add(1,2);
            System.out.println("result:"+result);
    
            result = arithmeticCalculator.div(200,0);
            System.out.println("result:"+result);
    
        }
    }
  • 相关阅读:
    GIT学习笔记(2):时光机穿梭与远程仓库
    CNN学习笔记:正则化缓解过拟合
    Java分布式:RPC(远程过程调用)
    设计模式:学习笔记(12)——代理模式
    算法:乐观锁与悲观锁
    Python:笔记(5)——错误、调试和测试
    算法:LRU(最近最少使用)
    Python:笔记(4)——高级特性
    方法论:带着问题找答案
    Cache-Aside模式
  • 原文地址:https://www.cnblogs.com/xjs1874704478/p/12024944.html
Copyright © 2011-2022 走看看