• Spring基础-07(Spring05-07:AOP)


    AOP配置文件版(Spring基础-06为注解版)

    MyMathCalculator.java:

    package com.atguigu.impl;
    
    import org.springframework.stereotype.Service;
    
    /**
     * @Title: MyMathCalculator
     * @Description:
     * @Author:
     * @Version: 1.0
     * @create 2020/6/7 19:43
     */
    public class MyMathCalculator /*implements Calculator*/ {
    
        //@Override
        public int add(int i, int j) {
            //System.out.println("【add】方法开始了,它使用的参数是:【"+i+"】,【"+j+"】");
            //考虑方法的兼容性
            //LogUtils.logStart(i, j);
            int result = i + j;
    //        System.out.println("【add】方法运行完成,计算结果是:【"+result+"】");
            System.out.println("方法内部执行");
            return result;
        }
    
        //@Override
        public int sub(int i, int j) {
            int result = i - j;
            System.out.println("方法内部执行");
            return result;
        }
    
        //@Override
        public int mul(int i, int j) {
            int result = i * j;
            System.out.println("方法内部执行");
            return result;
        }
    
        //@Override
        public int div(int i, int j) {
            int result = i / j;
            System.out.println("方法内部执行");
            return result;
        }
    }

    Calculator.java:

    package com.atguigu.inter;
    
    /**
     * 接口不加载在容器中
     * 实际上可以加,加了也不创建对象,只要一看这个组件是一个接口,
     * 相当于告诉Spring,ioc容器中可能有这种类型的组件
     */
    public interface Calculator {
    
        public int add(int i, int j);
    
        public int sub(int i, int j);
    
        public int mul(int i, int j);
    
        public int div(int i, int j);
    }

    LogUtils.java:

    package com.atguigu.utils;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.*;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    
    public class LogUtils {
    
        public static void logStart(JoinPoint joinPoint) {
            //获取目标方法运行时使用的参数
            Object[] args = joinPoint.getArgs();
            //获取到方法签名
            Signature signature = joinPoint.getSignature();
            String name = signature.getName();
            System.out.println("[LogUtils-前置][" + name + "]方法开始执行,使用的参数列表" + Arrays.asList(args));
        }
    
    
        public static void logReturn(JoinPoint joinPoint, Object result) {
            Signature signature = joinPoint.getSignature();
            String name = signature.getName();
            System.out.println("[LogUtils-返回][" + name + "]方法正常执行完成了,计算结果是" + result);
        }
    
        public static void logException(JoinPoint joinPoint, Exception exception) {
            System.out.println("[LogUtils-异常][" + joinPoint.getSignature().getName() + "]方法出现异常了,异常信息是:[" + exception + "],这个异常已经通知测试测试小组进行排查");
        }
    
        public static int logEnd(JoinPoint joinPoint) {
            System.out.println("[LogUtils-后置][" + joinPoint.getSignature().getName() + "]方法最终结束");
            return 0;
        }
    
        public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
            Object[] args = pjp.getArgs();
            String name = pjp.getSignature().getName();
            Object proceed = null;
            // idea ctrl + alt + t
            try {
                //利用反射调用目标方法即可,就是method.invoke(obj,args)
                //@Before
                System.out.println("[环绕前置通知]-[" + name + "方法开始]");
                proceed = pjp.proceed();
                //@AfterReturning
                System.out.println("[环绕返回通知]-[" + name + "方法返回,返回值为:" + proceed + "]");
            } catch (Exception e) {
                //@AfterThrowing
                System.out.println("[环绕异常通知]-[" + name + "方法出现异常],异常信息" + e.getCause());
                //为了让外界能知道这个异常,这个异常一定要抛出去
                throw new RuntimeException(e);
            } finally {
                //@After
                System.out.println("[环绕后置通知最终结束]-[" + name + "]方法结束");
            }
            //反射调用后的返回值也一定返回出去
            return proceed;
        }
    
    
    }

    ValidateAspect.java:

    package com.atguigu.utils;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.*;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    
    import java.util.Arrays;
    
    /**
     * @Title: ValidateApsect
     * @Description:
     * @Author:
     * @Version: 1.0
     * @create 2020/6/8 11:53
     */
    
    public class ValidateAspect {
    
        public void logStart(JoinPoint joinPoint) {
            //获取目标方法运行时使用的参数
            Object[] args = joinPoint.getArgs();
            //获取到方法签名
            Signature signature = joinPoint.getSignature();
            String name = signature.getName();
            System.out.println("[VaAspect-前置][" + name + "]方法开始执行,使用的参数列表" + Arrays.asList(args));
        }
    
        public void logReturn(JoinPoint joinPoint, Object result) {
            Signature signature = joinPoint.getSignature();
            String name = signature.getName();
            System.out.println("[VaAspect-返回][" + name + "]方法正常执行完成了,计算结果是" + result);
        }
    
        public void logException(JoinPoint joinPoint, Exception exception) {
            System.out.println("[VaAspect-异常][" + joinPoint.getSignature().getName() + "]方法出现异常了,异常信息是:[" + exception + "],这个异常已经通知测试测试小组进行排查");
        }
    
        public int logEnd(JoinPoint joinPoint) {
            System.out.println("[VaAspect-后置][" + joinPoint.getSignature().getName() + "]方法最终结束");
            return 0;
        }
    }

    applicationContext.xml:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:context="http://www.springframework.org/schema/context"
     5        xmlns:aop="http://www.springframework.org/schema/aop"
     6        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
     7 
     8     <context:component-scan base-package="com.atguigu"></context:component-scan>
     9 
    10     <!--基于注解的AOP步骤
    11         1.将目标类和切面类都加入到ioc容器中
    12         2.告诉spring哪个是切面类    @Aspect
    13         3.在切面类中使用5个通知注解来配置切面中的这些方法何时何地运行
    14         4.开启基于注解的AOP功能
    15     -->
    16 
    17     <!--开启基于注解的AOP功能:AOP名称空间-->
    18     <!--<aop:aspectj-autoproxy></aop:aspectj-autoproxy>-->
    19 
    20     <!--基于配置的AOP-->
    21     <bean class="com.atguigu.impl.MyMathCalculator" id="myMathCalculator"></bean>
    22     <bean class="com.atguigu.utils.ValidateAspect" id="validateAspect"></bean>
    23     <bean class="com.atguigu.utils.LogUtils" id="logUtils"></bean>
    24 
    25     <!--需要AOP名称空间-->
    26     <aop:config>
    27         <!--全局-->
    28         <aop:pointcut id="globalPoint" expression="execution(* com.atguigu.impl.*.*(..))"/>
    29 
    30         <!--普通前置 ———— 目标方法 ——(环绕执行后置/返回)——普通后置 ———— 普通返回 -->
    31         <!--指定切面  @Aspect-->
    32         <!--按照配置顺序进行切入,可以使用order进行修改-->
    33         <aop:aspect ref="logUtils" order="3">
    34             <!--配置哪个方法是前置通知 method指定方法名
    35                 logStart @Before("切入点表达式")
    36             -->
    37             <!--当前切面能用的-->
    38             <aop:around method="myAround" pointcut-ref="globalPoint"/>
    39             <aop:pointcut id="myPoint" expression="execution(* com.atguigu.impl.*.*(..))"/>
    40             <aop:before method="logStart" pointcut="execution(* com.atguigu.impl.*.*(..))"/>
    41             <aop:after-returning method="logReturn" pointcut-ref="myPoint" returning="result"/>
    42             <aop:after-throwing method="logException" pointcut-ref="myPoint" throwing="exception"/>
    43             <aop:after method="logEnd" pointcut-ref="myPoint"/>
    44         </aop:aspect>
    45         <aop:aspect ref="validateAspect"></aop:aspect>
    46         <!--在切面类中使用5个通知注解来配置切面中的这些方法何时何地运行-->
    47 
    48         <aop:aspect ref="validateAspect" order="-1">
    49             <aop:before method="logStart" pointcut-ref="globalPoint"/>
    50             <aop:after-returning method="logReturn" pointcut-ref="globalPoint" returning="result"/>
    51             <aop:after-returning method="logReturn" pointcut-ref="globalPoint" returning="result"/>
    52             <aop:after-throwing method="logException" pointcut-ref="globalPoint" throwing="exception"/>
    53             <aop:after method="logEnd" pointcut-ref="globalPoint"/>
    54         </aop:aspect>
    55     </aop:config>
    56 
    57     <!--
    58         总结:
    59             注解:快速方便
    60             配置:功能完善,重要的用配置,不重要的用注解
    61     -->
    62 
    63 </beans>

    AOPTest.java:

    package com.atguigu.test;
    
    import com.atguigu.impl.MyMathCalculator;
    import com.atguigu.inter.Calculator;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @Title: AOPTest
     * @Description:
     * @Author:
     * @Version: 1.0
     * @create 2020/6/7 23:35
     */
    //@ContextConfiguration(locations = "classpath:applicationContext.xml")
    //@RunWith(SpringJUnit4ClassRunner.class)
    public class AOPTest {
    
        ApplicationContext ioc = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
    
        @Test
        public void test(){
            MyMathCalculator bean = ioc.getBean(MyMathCalculator.class);
            bean.add(1,2);
            System.out.println("============");
    //        bean.div(1,0);
            bean.div(1,1);
        }
    }
  • 相关阅读:
    Tensorflow基础教程11:常用模块 tf.data :数据集的构建与预处理
    Tensorflow基础教程10:常用模块 TensorBoard:训练过程可视化
    Tensorflow基础教程9:常用模块 tf.train.Checkpoint 之变量的保存与恢复
    Tensorflow基础教程8:自定义层、损失函数和评估指标
    OC原理之多线程中的锁(一)
    OC原理之多线程(二)
    OC原理之多线程(一)
    OC原理之RunLoop的运行逻辑
    OC原理RunLoop(一)
    前端模块化:CommonJS,AMD,CMD,ES6
  • 原文地址:https://www.cnblogs.com/116970u/p/13069629.html
Copyright © 2020-2023  润新知