首页 > 技术文章 > Spring AOP:面向切面编程,AspectJ,是基于spring 的xml文件的方法

lxnlxn 2016-09-13 20:08 原文

导包等不在赘述;

建立一个接口:ArithmeticCalculator,没有实例化的方法;

package com.atguigu.spring.aop.impl.panpan;

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);
}

建立一个类:ArithmeticCalculatorImpl 继承于接口:ArithmeticCalculator,实现接口中没有实例化的方法

package com.atguigu.spring.aop.impl.panpan;

import org.springframework.stereotype.Component;

public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

    @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 mul(int i, int j) {
        int result=i*j;
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result=i/j;
        return result;
    }

}

建立类:ArithmeticCalculatorLoggingProxy,实例化一些面向切面编程的方法

package com.atguigu.spring.aop.impl.panpan;


import java.util.Arrays;

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

public class ArithmeticCalculatorLoggingProxy {
    
    //前置通知的方法,在xml文件中可以通过method这个属性获取该方法的方法名,joinPoint是切点,
    public void beforeMethod(JoinPoint joinPoint){
        //获取方法名,和参数值,参数值要多个,所以用数组集合的方法
        String methodName=joinPoint.getSignature().getName();
        Object[] args=joinPoint.getArgs();
        
        System.out.println("The method "+methodName+" begains "+Arrays.asList(args));
    }
    
    //后置通知的方法
    public void afterMethod(JoinPoint joinPoint){
        //获取方法名,和参数值
        String methodName=joinPoint.getSignature().getName();
        System.out.println("The method "+methodName+ " ends");
    }
    
    //返回通知的方法
    public void afterReturning(JoinPoint joinPoint,Object result){
        //获取方法名,和参数值
        String methodName=joinPoint.getSignature().getName();
        System.out.println("The method "+methodName+ " *** ends :"+result);
    }
    
    //异常通知的方法
    public void afterThrowing(JoinPoint joinPoint, Exception e){
        String methodName=joinPoint.getSignature().getName();
        System.out.println("The method "+methodName+ " Exception :"+ e);
    }
    
    //环绕通知的
    public Object aroundMethod(ProceedingJoinPoint pjp){
        Object result=null;
        //获取方法名
        String methodName=pjp.getSignature().getName();
        try {
            //前置通知,Arrays.asList(pjp.getArgs())为该方法的参数个数,为数组集合
            System.out.println("The method "+methodName+" begains "+Arrays.asList(pjp.getArgs()));
            
            //执行目标方法
            result=pjp.proceed();
            
            //返回通知
            System.out.println("The method "+methodName+ "  ends with :"+result);
            
        } catch (Throwable e) {
            //异常通知
            System.out.println("The method " +methodName+ " occurs exception "+ e);
            e.printStackTrace();
        }
        //后置通知
        System.out.println("The method " + methodName + " ends");
        return result;
    }
}

建立spring的xml文件,进行bean和AOP的配置

<!-- 配置bean ,全类名是继承接口类的全类名-->
<bean id="arithmeticCalculator" 
        class="com.atguigu.spring.aop.impl.panpan.ArithmeticCalculatorImpl"></bean>
        
    <!-- 配置切面的bean ,全类名是实现切面编程的类全类名-->    
    <bean id="arithmeticCalculatorLoggingProxy" 
    class="com.atguigu.spring.aop.impl.panpan.ArithmeticCalculatorLoggingProxy"></bean>
    
    <!-- 配置AOP -->
    <aop:config>
        <!-- 配置切点表达式,全类名为接口的全类名 -->
        <aop:pointcut expression="execution(* com.atguigu.spring.aop.impl.panpan.ArithmeticCalculator.*(int,int))" 
        id="pointcut"/>
        
        <!-- 配置切面及通知 method中的为方法名,-->
        <aop:aspect ref="arithmeticCalculatorLoggingProxy" order="1">
            <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="afterMethod" pointcut-ref="pointcut" />
        </aop:aspect>
    </aop:config>

建立类Main,进行测试

ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.test.xml");
//ArithmeticCalculator,是一个接口类,注解的是继承该接口的类
ArithmeticCalculator impl=(ArithmeticCalculator) ctx.getBean("arithmeticCalculator");
        
System.out.println(impl.getClass().getName());
        
int result=impl.add(12,2);
System.out.println(result);
        
double result2=impl.div(12, 2);
System.out.println(result2);

 

推荐阅读