😀前言
本篇的Spring-AOP系类文章第五篇讲解了演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP
🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉
💖演示spring AOP的切入表达式重用和优先级问题以及怎么实现基于xml的AOP
💞AOP-切入点表达式重用
🤔应用实例
● 切入点表达式重用
为了统一管理切入点表达式,可以使用切入点表达式重用技术。
● 应用案例: 在原来的代码上修改即可
- 修改SmartAnimalAspect.java
/** * 使用切面编程来替代原来的动态代理类,机制是一样的. * @author Administrator */ @Aspect //表示这个类是一个切面类 @Component //需要加入到IOC 容器 public class SmartAnimalAspect { //=====AOP-切入点表达式重用start ====== /* * 这样定义的一个切入点表达式,就可以在其它地方直接使用 */ @Pointcut(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))") public void myPointCut() { } // @Before(value="execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))") @Before(value = "myPointCut()") public void showBeginLog(JoinPoint joinPoint) { //前置方法 //得到方法的签名 // 调用前置通知对应的方法签名: float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float) Signature signature = joinPoint.getSignature(); //得到方法名. String method_name = signature.getName(); //得到参数 Object[] args = joinPoint.getArgs(); System.out.println("前置通知" + "--调用的方法是" + method_name + "--参数是 --" + Arrays.asList(args)); } //@After(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))") @After(value = "myPointCut()") public void showFinallyEndLog() { System.out.println("最终通知-- AOP-切入点表达式重用"); } /** * returning = "res", Object res 名称保持一致 * @param joinPoint * @param res 调用getSum() 返回的结果 */ @AfterReturning(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))", returning = "res") public void showSuccessEndLog(JoinPoint joinPoint, Object res) { System.out.println("返回通知" + "--结果是--" + res); } @AfterThrowing(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))", throwing = "throwable") public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) { System.out.println("异常通知-- 异常信息--" + throwable); } //=====AOP-切入点表达式重用end ======
测试AopJoinPointTest.java
🥰AOP-切面优先级问题
😉应用实例
● 切面优先级问题:
如果同一个方法,有多个切面在同一个切入点切入,那么执行的优先级如何控制.
● 基本语法:
@order(value=n) 来控制 n值越小,优先级越高
● 案例说明
- 创建\SmartAnimalAspect2.java
@Aspect //表示这个类是一个切面类 @Order(value = 2) @Component //需要加入IOC 容器 public class SmartAnimalAspect2 { /* * 这样定义的一个切入点表达式,就可以在其它地方直接使用 */ @Pointcut(value = "execution(public float com.wyxedu.spring.aop.joinpoint.SmartDog.getSum(float, float))") public void myPointCut() { } @Before(value = "myPointCut()") public void showBeginLog(JoinPoint joinPoint) { System.out.println("前置通知SmartAnimalAspect2 showBeginLog"); } @AfterReturning(value = "myPointCut()", returning = "res") public void showSuccessEndLog(JoinPoint joinPoint, Object res) { System.out.println("返回通知SmartAnimalAspect2 showSuccessEndLog"); } @AfterThrowing(value = "myPointCut()", throwing = "throwable") public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) { System.out.println("异常通知SmartAnimalAspect2 showExceptionLog"); } @After(value = "myPointCut()") public void showFinallyEndLog() { System.out.println("最终通知SmartAnimalAspect2 showFinallyEndLog"); } }
- 修改SmartAnimalAspect.java
测试
- 如何理解输出的信息顺序,类似Filter 的过滤链式调用机制. (示意图-就比较清楚了.)
💥注意事项和细节说明
如何理解输出的信息顺序,类似 Filter 的过滤链式调用机制. (示意图-就比较清楚了.)
- 不能理解成:优先级高的每个消息通知都先执行,这个和方法调用机制(和 Filter 过滤器链式调用类似)
- 如何理解执行顺序
😊AOP-基于 XML 配置 AOP
● 基本说明:
前面我们是通过注解来配置 aop 的,在 spring 中,我们也可以通过 xml 的方式来配置 AOP
😀代码示例
实现步骤
- 创建包com.wyxedu.spring.aop.xml , SmartAnimalable.java 和SmartDog.java 从其它包拷贝即可
- 创建SmartAnimalAspect.java , 从com.wyxedu.spring.aop 包拷贝,并去掉所有注解
具体实现
- 创建接口SmartAnimalable
public interface SmartAnimalable { //求和 float getSum(float i, float j); //求差 float getSub(float i, float j); }
- 创建SmartAnimalAspect类注意没有注解
public class SmartAnimalAspect { public void showBeginLog(JoinPoint joinPoint) { //通过连接点对象joinPoint 可以获取方法签名 Signature signature = joinPoint.getSignature(); System.out.println("SmartAnimalAspect-XML配置-切面类showBeginLog()[使用的myPointCut()]-方法执行前-日志-方法名-" + signature.getName() + "-参数 " + Arrays.asList(joinPoint.getArgs())); } public void showSuccessEndLog(JoinPoint joinPoint, Object res) { Signature signature = joinPoint.getSignature(); System.out.println("SmartAnimalAspect-XML配置-切面类showSuccessEndLog()-方法执行正常结束-日志-方法名-" + signature.getName() + " 返回的结果是=" + res); } public void showExceptionLog(JoinPoint joinPoint, Throwable throwable) { Signature signature = joinPoint.getSignature(); System.out.println("SmartAnimalAspect-XML配置-切面类showExceptionLog()-方法执行异常-日志-方法名-" + signature.getName() + " 异常信息=" + throwable); } public void showFinallyEndLog(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); System.out.println("SmartAnimalAspect-XML配置-切面类showFinallyEndLog()-方法最终执行完毕-日志-方法名-" + signature.getName()); } }
- 创建SmartDog注意没有注解
public class SmartDog implements SmartAnimalable { @Override public float getSum(float i, float j) { float result = i + j; //result = 1 / 0; //模拟一个算术异常 System.out.println("方法内部打印result = " + result); return result; } @Override public float getSub(float i, float j) { float result = i - j; System.out.println("方法内部打印result = " + result); return result; } }
- 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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"> <!--使用XML配置,完成AOP编程--> <!--配置一个切面类对象-bean--> <bean class="com.spring.aop.xml.SmartAnimalAspect" id="smartAnimalAspect"/> <!--配置一个SmartDog对象-bean--> <bean class="com.spring.aop.xml.SmartDog" id="smartDog"/> <!--配置切面类, 细节一定要引入 xmlns:aop--> <aop:config> <!--配置切入点--> <aop:pointcut id="myPointCut" expression="execution(public float com.spring.aop.xml.SmartDog.getSum(float, float)))"/> <!--配置切面的前置,返回, 异常, 最终通知--> <aop:aspect ref="smartAnimalAspect" order="10"> <!--配置前置通知--> <aop:before method="showBeginLog" pointcut-ref="myPointCut"/> <!--返回通知--> <aop:after-returning method="showSuccessEndLog" pointcut-ref="myPointCut" returning="res"/> <!--异常通知--> <aop:after-throwing method="showExceptionLog" pointcut-ref="myPointCut" throwing="throwable"/> <!--最终通知--> <aop:after method="showFinallyEndLog" pointcut-ref="myPointCut"/> <!--配置环绕通知--> <!--<aop:around method=""/>--> </aop:aspect> </aop:config> </beans>
测试
public class AopAspectjXMLTest { @Test public void testAspectByXML() { ApplicationContext ioc = new ClassPathXmlApplicationContext("beans09.xml"); SmartAnimalable smartAnimalable = ioc.getBean(SmartAnimalable.class); smartAnimalable.getSum(10, 2); } }
😄总结
本文详细的讲解了spring AOP的切入表达式重用和AOP优先级问题以及AOP怎么实现基于xml的aop
😍Spring-AOP系类文章
第一篇-> Spring-AOP的基本介绍以及通过先动态代理方式实现
第二篇-> Spring-动态代理深入了解
第三篇-> 再次分析-提出 Spring AOP-真正的AOP
第四篇-> spring-aop的切入表达式和JoinPoint的使用以及怎么返回通知获取结果和在异常通知中获取异常还有环绕通知
文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞