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

applicationContext-xml.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.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!--配置bean -->
    <bean id="arithmeticCalculator" class="com.aff.spring.aop.imlp.xml.ArithmeticCalculatorImpl"></bean>

    <!--配置切面的bean -->
    <bean id="loggingAspect" class="com.aff.spring.aop.imlp.xml.LoggingAspect"></bean>

    <!-- 配置AOP -->
    <aop:config>
        <!-- 配置切点表达式 -->
        <aop:pointcut
            expression="execution(* com.aff.spring.aop.imlp.xml.ArithmeticCalculator.*(..))"
            id="pointcut" />
            <!-- 配置切面及通知 -->
            <aop:aspect ref="loggingAspect" order="2">
            <aop:before method="beforeMethod" pointcut-ref="pointcut"/>
            <aop:after method="afterMethod" pointcut-ref="pointcut"/>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="e"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
            <!--  
            <aop:around method="aroundMethod" pointcut-ref="pointcut"/> 
             -->
            </aop:aspect>

    </aop:config>
</beans>

LoggingAspect.java

package com.aff.spring.aop.imlp.xml;

import java.util.Arrays;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

//把这个类声明为切面,需要把这个类放到IOC容器中, 再声明为一个切面
public class LoggingAspect {
    
    /**
     * 定义一个方法, 用于声明切入点表达式,一般,该方法中不再需要添加其他代码
     * 
     * @Pointut 声明切点表达式
     *    后面的其他通知 直接使用方法名来引用当前的切点表达式 
     */
    public void  declareJointPointExpression(){
        
    }
    
    //声明该方法是一个前置通知, 在目标方法开始之前执行
    public void  beforeMethod(JoinPoint joinPoint){
        String methodName =  joinPoint.getSignature().getName();
        List<Object> args =  Arrays.asList(joinPoint.getArgs());
        System.out.println("The method " +methodName+"begins  with"+args);
    }
    //后置通知:在目标方法执行后(无论 是否发生异常) ,执行的通知
    //在后置通知中还不能访问目标方法执行的结果
    //第一个*:任意返回值类型;   第二个*:包下的任意类;  第三个*:任意方法; .. : 任意参数
    public void afterMethod(JoinPoint joinPoint){
        String methodName =  joinPoint.getSignature().getName();
        System.out.println("The method " +methodName+"ends ");
    }
    
    
    /**
    *  返回通知
     * 在方法正常结束后执行的代码
     * 返回通知是可以访问到方法的返回值
     * @param joinPoint
     */
    public  void  afterReturning(JoinPoint joinPoint,Object result ){
        String methodName =  joinPoint.getSignature().getName();
        System.out.println("The method " +methodName+"ends with "+result);
    }
    
    /**
     * 异常通知
     * 在目标方法出现异常时 会执行的代码
     * 可以访问到异常对象,且可以指定出现特定异常时在执行通知代码
     * @param joinPoint
     * @param ex
     */
    public void  afterThrowing(JoinPoint joinPoint,Exception e){
        String methodName =  joinPoint.getSignature().getName();
        System.out.println("The method " +methodName+"ocurs  exception :"+e);
    }        
    
    /**
     * 转绕通知需要携带 ProceedingJoinPoint 类型的参数
     * 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法
     * 且环绕通知必须有返回值
     * @param pjd
     */
    
    public  Object  aroundMethod(ProceedingJoinPoint pjd){
        Object result =null;
        String methodName=   pjd.getSignature().getName();
        //执行目标方法
        try {
            //前置通知
            System.out.println("The method " +methodName+"begins  with"+Arrays.asList(pjd.getArgs()));
            
            //执行目标方法
            result = pjd.proceed();
            
            //返回通知
            System.out.println("The method "+methodName +"end with"+result);
        } catch (Throwable e) {
            //异常通知
            System.out.println("The method"+methodName+" ocurs  exception :"+e);
            throw new RuntimeException(e);
        }
        System.out.println("The method "+methodName +"ends");
        return result;
    }
    
}

Main

package com.aff.spring.aop.imlp.xml;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-xml.xml");
        
        ArithmeticCalculator arithmeticCalculator = ctx.getBean(ArithmeticCalculator.class);
        
        int result = arithmeticCalculator.add(2, 3);
        System.out.println("result:"+result);
        
        int result2 = arithmeticCalculator.div(2, 1);
        System.out.println("result2:"+result2);
        
    }
}

运行如下

The method addbegins  with[2, 3]
The method addend with5
The method addends
result:5
The method divbegins  with[2, 1]
The method divend with2
The method divends
result2:2

目录

All that work will definitely pay off
原文地址:https://www.cnblogs.com/afangfang/p/12986930.html