Spring中基于xml的AOP实现详解
作者:蕾峰
这篇文章主要介绍了Spring中基于xml的AOP实现详解,基于xml与基于注解的AOP本质上是非常相似的,都是需要封装横切关注点,封装到切面中,然后把横切关注点封装为一个方法,再把该方法设置为当前的一个通知,再通过切入点表达式定位到横切点就可以了,需要的朋友可以参考下
基于xml的AOP实现
基于xml与基于注解的AOP本质上是非常相似的,都是需要封装横切关注点,封装到切面中,然后把横切关注点封装为一个方法,再把该方法设置为当前的一个通知,再通过切入点表达式定位到横切点就可以了,思路是非常相似的。
我们的接口代码如下所示:
package com.rgf.spring.aop.annotation.xml; import org.springframework.stereotype.Component; @Component public interface Calculator { int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); }
我们的实现类如下所示:
package com.rgf.spring.aop.annotation.xml; import org.springframework.stereotype.Component; /** * */ @Component public class CalculatorImpl implements Calculator { @Override public int add(int i, int j) { int result=i+j; System.out.println("方法内部,result:"+result); return result; } @Override public int sub(int i, int j) { int result=i-j; System.out.println("方法内部,result:"+result); return result; } @Override public int mul(int i, int j) { int result=i*j; System.out.println("方法内部,result:"+result); return result; } @Override public int div(int i, int j) { int result=i/j; System.out.println("方法内部,result:"+result); return result; } }
我们封装的切面方法如下所示:
package com.rgf.spring.aop.annotation.xml; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; import java.util.Arrays; @Component public class LoggerAspect { public void beforeAdviceMethod(JoinPoint joinPoint){ Signature signature = joinPoint.getSignature(); Object[] args = joinPoint.getArgs(); System.out.println("LoggerAspect,方法:"+signature.getName()+",参数:"+ Arrays.toString(args)); } public void afterAdviceMethod(JoinPoint joinPoint){ Signature signature = joinPoint.getSignature(); Object[] args = joinPoint.getArgs(); System.out.println("LoggerAspect,方法:"+signature.getName()+",执行完毕"); } public void afterReturningAdviceMethod(JoinPoint joinPoint,Object result){ Signature signature = joinPoint.getSignature(); Object[] args = joinPoint.getArgs(); System.out.println("LoggerAspect,方法:"+signature.getName()+",结果:"+result); } public void afterThrowingAdviceMethod(JoinPoint joinPoint,Throwable ex){ Signature signature = joinPoint.getSignature(); System.out.println("LoggerAspect,方法:"+signature.getName()+",异常:"+ex); } public Object aroundAdviceMethod(ProceedingJoinPoint joinPoint){ Object result=null; try { System.out.println("环绕通知-->前置通知"); //表示目标对象方法的执行 result = joinPoint.proceed(); System.out.println("环绕通知-->返回通知"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("环绕通知-->异常通知"); }finally { System.out.println("环绕通知-->后置通知"); } return result; } }
我们封装的切面如下所示:
package com.rgf.spring.aop.annotation.xml; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; /** * 切面的优先级: * 可以通过@Order注解的value属性设置优先级,默认值Integer的最大值 * @Order注解的value属性值越小,优先级越高 * */ @Component public class ValidateAspect { public void beforeMethod(){ System.out.println("ValidateAspect-->前置通知"); } }
我们的配置文件如下:
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描组件--> <context:component-scan base-package="com.rgf.spring.aop.annotation.xml"></context:component-scan> <!-- <cop:aspectj-autoproxy:开启基于注解的aop--> <aop:config> <!--设置一个公共的切入点表达式--> <aop:pointcut id="pointcut" expression="execution(* com.rgf.spring.aop.annotation.xml.CalculatorImpl.*(..))"/> <!--aop:aspect:将IOC容器中的某个bean(某个组件)设置为切面,通过ref引用某一个besn的id,就可以将当前这一个bean来设置为一个切面--> <!--aop:advisor:设置当前的通知--> <!--aop:pointcut:设置切入点表达式--> <aop:aspect ref="loggerAspect"> <aop:before method="beforeAdviceMethod" pointcut-ref="pointcut"></aop:before> <aop:after method="afterAdviceMethod" pointcut-ref="pointcut"></aop:after> <aop:after-returning method="afterReturningAdviceMethod" returning="result" pointcut-ref="pointcut"></aop:after-returning> <aop:after-throwing method="afterThrowingAdviceMethod" throwing="ex" pointcut-ref="pointcut"></aop:after-throwing> <aop:around method="aroundAdviceMethod" pointcut-ref="pointcut"></aop:around> </aop:aspect> <!--order进行设置他的优先级.设置的值越小,优先级越高--> <aop:aspect ref="validateAspect" order="1"> <aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before> </aop:aspect> </aop:config> </beans>
我们进行测试如下所示:
package com.rgf.spring.test; import com.rgf.spring.aop.annotation.xml.Calculator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AOPByXMLTest { @Test public void testAOPByXML(){ ApplicationContext ioc = new ClassPathXmlApplicationContext("aop-xml.xml"); Calculator calculator = ioc.getBean(Calculator.class); calculator.add(1,1); } }
我们进行运行之后如下所示:
到此这篇关于Spring中基于xml的AOP实现详解的文章就介绍到这了,更多相关基于xml的AOP实现内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!