基于XML配置的Sping AOP详解

一、编写基本处理方法

package com.kang.sping.xml.aop;

public class Math{
    //加
    public int add(int n1,int n2){
        int result=n1+n2;
        System.out.println(n1+"+"+n2+"="+result);
        return result;
    }
    
    //减
    public int sub(int n1,int n2){
        int result=n1-n2;
        System.out.println(n1+"-"+n2+"="+result);
        return result;
    }
    
    //乘
    public int mut(int n1,int n2){
        int result=n1*n2;
        System.out.println(n1+"*"+n2+"="+result);
        return result;
    }
    
    //除
    public int div(int n1,int n2){
        int result=n1/n2;
        System.out.println(n1+"/"+n2+"="+result);
        return result;
    }
}

二、编写通知类

package com.kang.sping.xml.aop;

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

/**
 * 通知类,横切逻辑
 *
 */
public class Advices {
    
    public void before(JoinPoint jp){
        System.out.println("----------前置通知----------");
        System.out.println(jp.getSignature().getName());
    }
    
    public void after(JoinPoint jp){
        System.out.println("----------最终通知----------");
    }
    
    public void afterReturning(JoinPoint joinPoint, Object result){
    	//定义AfterReturning通知方法
    }
    
    public void afterThrowing(JoinPoint joinPoint, Exception e){
    	//定义AfterThrowing通知方法
    }
    
    public Object around(ProceedingJoinPoint pjd){
    	//定义Around通知方法
    	return null;
    }
}

三、配置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 id="math" class="com.kang.sping.xml.aop.Math"></bean>
	
	<!-- 配置切面的 bean.切面 Bean 必须有一个标示符id, 供 <aop:aspect> 元素引用 -->
	<bean id="advices" class="com.kang.sping.xml.aop.Advices"></bean>
	<!-- 可以定义多个切面bean,例如再定义一个日志bean -->
	<!-- <bean id="loggingAspect" class="com.kang.spring.xml.aop.LoggingAspect"></bean> -->
	<!-- aop配置 -->
	
	<!-- 
	proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。 
	如果proxy-target-class 属性值被设置为true,那么基于类的代理将起作用(这时需要cglib库)。 
	如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK 基于接口的代理。
	spring使用aop时需要设置proxy-target-class="true" ,否则无法依赖注入
	 -->
	<!-- 所有的 Spring AOP 配置都必须定义在 <aop:config> 元素内部 -->
	<aop:config proxy-target-class="true">
	
		<!-- 
		配置切点表达式,id标示了该切点以供下面引用。切入点必须定义在 <aop:aspect> 元素下, 
		或者直接定义在 <aop:config>元素下. 定义在 <aop:aspect> 元素下: 只对当前切面有效。
		定义在 <aop:config> 元素下: 对所有切面都有效。
		基于 XML的 AOP 配置不允许在切入点表达式中用名称引用其他切入点. 
		-->
		<aop:pointcut expression="execution(* com.kang.sping.xml.aop.Math.*(..))"
			id="pointcut1" />
			
		<!--
		配置切面 .每个切面而言, 都要创建一个 <aop:aspect> 元素来为具体的切面实现,
		用以引用具体bean的方法 这里配置为ref="advices",则可以调用advices对应的类中的方法
		 -->
		<aop:aspect ref="advices">
		
			<!--配置连接通知方法与切点,method 属性指定切面类中通知方法的名称 -->
			<aop:before method="before" pointcut-ref="pointcut1" />
			<aop:after method="after" pointcut-ref="pointcut1" />
			<!-- 
			配置其他通知方法 
			<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut1" throwing="e"/> 
			<aop:after-returning method="afterReturning" pointcut-ref="pointcut1" returning="result"/> 
			<aop:around method="around" pointcut-ref="pointcut1"/>
			 -->
		</aop:aspect>
		
		<!--aspect里面有一个order属性,order属性的数字就是横切关注点的优先级顺序 -->
		<!-- 
		可以配置多个切面 
		<aop:aspect ref="loggingAspect" order="1"> 
		      <aop:before method="doLogging" pointcut-ref="pointcut1" /> </aop:aspect> 
		 -->
	</aop:config>






</beans>





四、编写测试方法

package com.kang.sping.xml.aop;

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

public class Test {

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-xml.xml");
        Math math = ctx.getBean("math", Math.class);
        int n1 = 100, n2 = 5;
        math.add(n1, n2);
        math.sub(n1, n2);
        math.mut(n1, n2);
        math.div(n1, n2);
    }

}


五、运行结果




六、总结

正常情况下, 基于注解的声明要优先于基于 XML 的声明. 通过 AspectJ 注解, 切面可以与 AspectJ 兼容, 而基于 XML 的配置则是 Spring 专有的. 由于 AspectJ 得到越来越多的 AOP 框架支持, 所以以注解风格编写的切面将会有更多重用的机会。当使用 XML 声明切面时, 需要在 <beans> 根元素中导入 aop Schema命名空间。



原文地址:https://www.cnblogs.com/kangsir/p/6653243.html