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

原文地址:https://www.cnblogs.com/yy3b2007com/p/9131253.html