Spring-AOP @AspectJ进阶之绑定抛出的异常

简介: Spring-AOP @AspectJ进阶之绑定抛出的异常

概述


和通过切点函数绑定连接点信息不同,连接点抛出的异常必须使用AfterThrowing注解的throwing成员进行绑定


实例


代码已托管到Github—> https://github.com/yangshangwei/SpringMaster


aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcwOTEzMDgyODQxNDQy.png


业务类

package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.springframework.stereotype.Component;
@Component
public class BussinessException {
  public void dealBussiness(String bussinessName) {
    System.out.println("dealBussiness executed");
    // just a demo code ,in fact it's not cautious
    if (bussinessName != null && "bug".equals(bussinessName))
      throw new IllegalArgumentException("iae Exception");
    else
      throw new RuntimeException("re Exception");
  }
}


切面

package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
/**
 * 
 * 
 * @ClassName: BindReturnValueAspect
 * 
 * @Description: @Aspect标注的切面,
 *               和通过切点函数绑定连接点信息不同,连接点抛出的异常必须使用AfterThrowing注解的throwing成员进行绑定
 * 
 *               (1)处throwing指定的异常名和(2)处入参的异常名相同,这个异常增强只在连接点抛出的异常instanceof
 *               IllegalArgumentException才匹配,增强方法通过iae参数可以访问抛出的异常对象。
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月12日 下午5:47:23
 */
@Aspect
public class BindExceptionAspect {
  // (1)
  @AfterThrowing(value = "target(com.xgj.aop.spring.advisor.aspectJAdvance.bindException.BussinessException)", throwing = "iae")
  public void crossCuttingCode(IllegalArgumentException iae) {// (2)
    System.out.println("----bindException()----");
    System.out.println("exception:" + iae.getMessage());
    System.out.println("----bindException()----");
  }
}


(1)处throwing指定的异常名和(2)处入参的异常名相同,这个异常增强只在连接点抛出的异常instanceof IllegalArgumentException才匹配,增强方法通过iae参数可以访问抛出的异常对象。


配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  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">
<!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.bindException"/>
<!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.bindException.BindExceptionAspect"/>
</beans>

单元测试

package com.xgj.aop.spring.advisor.aspectJAdvance.bindException;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class BindExceptionAspectTest {
  @Test
  public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext(
        "classpath:com/xgj/aop/spring/advisor/aspectJAdvance/bindException/conf-bindException.xml");
    ctx.getBean("bussinessException", BussinessException.class)
        .dealBussiness("bug");
  }
}


输出结果

2017-09-12 20:26:25,344  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@3695de1a: startup date [Tue Sep 12 20:26:25 BOT 2017]; root of context hierarchy
2017-09-12 20:26:25,458  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/bindException/conf-bindException.xml]
dealBussiness executed
----bindException()----
exception:iae Exception
----bindException()----


可见当sdealBussiness(“bug”)抛出异常后,异常增强起效,处理完成后,再向外抛出IllegalArgumentException。如果将①处的代码调整为dealBussiness(“bug2”)后,再运行代码,将只看到异常输出的信息,异常增强没有任何动作,这是因为RuntimeException 不按类型匹配于 IllegalArgumentException,切点不匹配。


aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcwOTEzMDgzMzA2NDg2.png


总结


通过切点复合运算,你可以定义出各种复杂的切点,使切点表达式的能力进一步提升。


你可以直接使用切点复合运算符对切点函数进行运算,也可以通过切点名引用其它命名切点。


当对同一个连接点织入多个增强时,你必须考虑让切面类实现Ordered接口,此外还必须合理计划同一个切面类中增强方法的声明顺序,因为这些信息都会影响到增强的织入顺序。


在@AspectJ的切点表达式中,大多数的切点函数都可以绑定连接点方法的入参,以便增强方法访问连接点信息。


此外,你也可以简单地将增强方法的第一个入参定义为JoinPoint访问连接点的上下文。

相关文章
|
1月前
|
Dubbo Java 应用服务中间件
深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案
本文深入探讨了“dubbo+nacos+springboot3的native打包成功后运行出现异常”的原因及解决方案。通过检查GraalVM版本兼容性、配置反射列表、使用代理类、检查配置文件、禁用不支持的功能、查看日志文件、使用GraalVM诊断工具和调整GraalVM配置等步骤,帮助开发者快速定位并解决问题,确保服务的正常运行。
53 1
|
2月前
|
Java API Spring
springBoot:注解&封装类&异常类&登录实现类 (八)
本文介绍了Spring Boot项目中的一些关键代码片段,包括使用`@PathVariable`绑定路径参数、创建封装类Result和异常处理类GlobalException、定义常量接口Constants、自定义异常ServiceException以及实现用户登录功能。通过这些代码,展示了如何构建RESTful API,处理请求参数,统一返回结果格式,以及全局异常处理等核心功能。
|
2月前
|
Java 关系型数据库 数据库连接
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第3天】Spring Boot项目中数据库连接问题可能源于配置错误或依赖缺失。YAML配置文件的格式不正确,如缩进错误,会导致解析失败;而数据库驱动不匹配、连接字符串或认证信息错误同样引发连接异常。解决方法包括检查并修正YAML格式,确认配置属性无误,以及添加正确的数据库驱动依赖。利用日志记录和异常信息分析可辅助问题排查。
346 10
|
2月前
|
Java 关系型数据库 MySQL
SpringBoot项目使用yml文件链接数据库异常
【10月更文挑战第4天】本文分析了Spring Boot应用在连接数据库时可能遇到的问题及其解决方案。主要从四个方面探讨:配置文件格式错误、依赖缺失或版本不兼容、数据库服务问题、配置属性未正确注入。针对这些问题,提供了详细的检查方法和调试技巧,如检查YAML格式、验证依赖版本、确认数据库服务状态及用户权限,并通过日志和断点调试定位问题。
193 6
|
4月前
|
前端开发 小程序 Java
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
本文详细介绍了如何在SpringBoot项目中统一处理接口返回结果及全局异常。首先,通过封装`ResponseResult`类,实现了接口返回结果的规范化,包括状态码、状态信息、返回信息和数据等字段,提供了多种成功和失败的返回方法。其次,利用`@RestControllerAdvice`和`@ExceptionHandler`注解配置全局异常处理,捕获并友好地处理各种异常信息。
2057 0
【规范】SpringBoot接口返回结果及异常统一处理,这样封装才优雅
|
4月前
|
Java Spring 开发者
Spring 框架配置属性绑定大比拼:@Value 与 @ConfigurationProperties,谁才是真正的王者?
【8月更文挑战第31天】Spring 框架提供 `@Value` 和 `@ConfigurationProperties` 两种配置属性绑定方式。`@Value` 简单直接,适用于简单场景,但处理复杂配置时略显不足。`@ConfigurationProperties` 则以类级别绑定配置,简化代码并更好组织配置信息。本文通过示例对比两者特点,帮助开发者根据具体需求选择合适的绑定方式,实现高效且易维护的配置管理。
67 0
|
4月前
|
消息中间件 Java 开发工具
【Azure 事件中心】Spring Cloud Stream Event Hubs Binder 发送Event Hub消息遇见 Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially 异常
【Azure 事件中心】Spring Cloud Stream Event Hubs Binder 发送Event Hub消息遇见 Spec. Rule 1.3 - onSubscribe, onNext, onError and onComplete signaled to a Subscriber MUST be signaled serially 异常
|
4月前
|
Java Spring
【Azure 事件中心】Spring Boot 集成 Event Hub(azure-spring-cloud-stream-binder-eventhubs)指定Partition Key有异常消息
【Azure 事件中心】Spring Boot 集成 Event Hub(azure-spring-cloud-stream-binder-eventhubs)指定Partition Key有异常消息
|
4月前
|
Java Spring
【Azure 服务总线】Spring Cloud 的应用 使用Service Bus 引起 org.springframework.beans.BeanInstantiationException 异常,无法启动
【Azure 服务总线】Spring Cloud 的应用 使用Service Bus 引起 org.springframework.beans.BeanInstantiationException 异常,无法启动
|
4月前
|
NoSQL Java Redis
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常
【Azure Spring Cloud】Java Spring Cloud 应用部署到Azure上后,发现大量的 java.lang.NullPointerException: null at io.lettuce.core.protocol.CommandHandler.writeSingleCommand(CommandHandler.java:426) at ... 异常