zoukankan      html  css  js  c++  java
  • Spring(二十):Spring AOP(四):基于配置文件的方式来配置 AOP

    基于配置文件的方式来配置 AOP

    前边三个章节《Spring(十七):Spring AOP(一):简介》、《Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)》、《Spring(十九):Spring AOP(三):切面的优先级、重复使用切入点表达式》讲解AOP时,都采用的是注解方式,如何使用配置文件的方式配置AOP呢?那么,本章节就会使用前边章节的例子,基于文件配置的方式实现AOP配置。

    第一步:新建好Spring AOP项目、导入依赖的jar包:

    第二步:添加Bean类,和切面类:

    IArithmeticCalculator.java接口类

    package com.dx.spring.beans.xml;
    
    /**
     * Description:Addition, subtraction, multiplication, and division
     */
    public interface IArithmeticCalculator {
        int add(int i, int j);
    
        int sub(int i, int j);
    
        int multi(int i, int j);
    
        int div(int i, int j);
    }

    ArithmeticCalculatorImpl.java组件

    package com.dx.spring.beans.xml;
    
    public class ArithmeticCalculatorImpl implements IArithmeticCalculator {
        @Override
        public int add(int i, int j) {
            int result = i + j;
            return result;
        }
    
        @Override
        public int sub(int i, int j) {
            int result = i - j;
            return result;
        }
    
        @Override
        public int multi(int i, int j) {
            int result = i * j;
            return result;
        }
    
        @Override
        public int div(int i, int j) {
            int result = i / j;
            return result;
        }
    }
    View Code

    LoggingAspect.java日志切面类:

    package com.dx.spring.beans.xml;
    
    import java.util.Arrays;
    import java.util.List;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    
    public class LoggingAspect {
        // 声明该方法为一个前置通知:在目标方法开始之前执行
        public void beforeMethod(JoinPoint joinpoint) {
            String methodName = joinpoint.getSignature().getName();
            List<Object> args = Arrays.asList(joinpoint.getArgs());
            System.out.println("before method " + methodName + " with " + args);
        }
    
        // 声明该方法为一个后置通知:在目标方法结束之后执行(无论方法是否抛出异常)。
        // 但是因为当方法抛出异常时,不能返回值为null,因此这里无法获取到异常值。
        public void afterMethod(JoinPoint joinpoint) {
            String methodName = joinpoint.getSignature().getName();
            List<Object> args = Arrays.asList(joinpoint.getArgs());
            System.out.println("after method " + methodName);
        }
    
        /**
         * 声明该方法为一个返回通知:在目标方法返回结果时后执行(当方法抛出异常时,无法执行)
         */
        public void afterReturningMethod(JoinPoint joinpoint, Object result) {
            String methodName = joinpoint.getSignature().getName();
            List<Object> args = Arrays.asList(joinpoint.getArgs());
            System.out.println(
                    "after method " + methodName + " with returning " + (result == null ? "NULL" : result.toString()));
        }
    
        /**
         * 定义一个异常通知函数: 只有在方法跑吹异常时,该方法才会执行,而且可以接受异常对象。
         */
        public void afterThrowingMethod(JoinPoint joinpoint, Exception ex) {
            String methodName = joinpoint.getSignature().getName();
            List<Object> args = Arrays.asList(joinpoint.getArgs());
            System.out.println(
                    "after method " + methodName + " occurs exception: " + (ex == null ? "NULL" : ex.getMessage()));
        }
    
        public Object aroundMethod(ProceedingJoinPoint pJoinPoint) throws Exception {
            String methodName = pJoinPoint.getSignature().getName();
            List<Object> args = Arrays.asList(pJoinPoint.getArgs());
    
            Object result = null;
            try {
                // 前置通知
                System.out.println("before method " + methodName + " with " + args);
                // 执行目标方法
                result = pJoinPoint.proceed();
                // 返回通知
                System.out.println("after method " + methodName + " returning " + result);
            } catch (Throwable ex) {
                // 异常通知
                System.out.println("after method " + methodName + " occurs exception: " + ex.getMessage());
                throw new Exception(ex);
            }
            // 后置通知
            System.out.println("after method " + methodName);
            return result;
        }
    }
    View Code

    ValidateAspect.java验证切面类:

    package com.dx.spring.beans.xml;
    
    public class ValidateAspect {
        public void beforeMethod() {
            System.out.println("validate...");
        }
    }
    View Code

    第三步:添加Spring配置文件spring-aop-xml.xml并配置AOP:

    前置、后置、返回、异常通知配置: 

    <?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.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
        <!-- 定义 Bean -->
        <bean id="arithmeticCalculator" class="com.dx.spring.beans.xml.ArithmeticCalculatorImpl"></bean>
        <!-- 配置切面的Bean -->
        <bean id="loggingAspect" class="com.dx.spring.beans.xml.LoggingAspect"></bean>
        <bean id="validateAspect" class="com.dx.spring.beans.xml.ValidateAspect"></bean>
    
        <!-- 配置AOP -->
        <aop:config>
            <!-- 配置切入点表达式 -->
            <aop:pointcut
                expression="execution(* com.dx.spring.beans.xml.IArithmeticCalculator.*(..))"
                id="pointcut" />
            <!-- 配置切面及通知 -->
            <aop:aspect ref="loggingAspect" order="2">
                <!-- 配置前置、后置、返回、异常通知 -->
                <aop:before method="beforeMethod" pointcut-ref="pointcut" />
                <aop:after method="afterMethod" pointcut-ref="pointcut" />
                <aop:after-returning method="afterReturningMethod" pointcut-ref="pointcut" returning="result" />
                <aop:after-throwing  method="afterThrowingMethod"  pointcut-ref="pointcut" throwing="ex" />
                <!-- 配置环绕通知 -->
                <!--<aop:around method="aroundMethod" pointcut-ref="pointcut" /> -->
            </aop:aspect>
            <aop:aspect ref="validateAspect" order="1">
                <aop:before method="beforeMethod" pointcut-ref="pointcut" />
            </aop:aspect>
        </aop:config>
    </beans>

    环绕配置:

    <aop:around method="aroundMethod" pointcut-ref="pointcut" />

    第四步:测试

    前置、后置、返回、异常通知配置:

    此时打印结果:

    validate...
    before method add with [1, 3]
    after method add
    after method add with returning 4
    4
    validate...
    before method div with [4, 2]
    after method div
    after method div with returning 2
    2

    环绕配置:

    此时打印结果:

    validate...
    before method add with [1, 3]
    after method add returning 4
    after method add
    4
    validate...
    before method div with [4, 2]
    after method div returning 2
    after method div
    2

  • 相关阅读:
    python练习题6.1输入列表,求列表元素和(eval输入应用)
    python练习题5.10两数之和(没有用字典)
    python练习题5.8能被3,5和7整除的数的个数(用集合实现)-没有用集合
    python练习题5.7列表去重(存在问题)
    python练习题5.6统计工龄
    python练习题5.5统计字符出现次数
    python练习题5.4分析活动投票情况
    python练习题5.3四则运算(用字典实现)
    Object.style.display = value的值完成显示隐藏
    js通过Object.style.property=new style;改变html样式
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/9131253.html
Copyright © 2011-2022 走看看