Spring AOP四种创建通知(拦截器)类型

简介: 1、Spring只支持方法拦截,也就是说,只能在方法的前后进行拦截,而不能在属性前后进行拦截。 2、Spring支持四种拦截类型:目标方法调用前(before),目标方法调用后(after),目标方法调用前后(around),以及目标方法抛出异常(throw)。

1、Spring只支持方法拦截,也就是说,只能在方法的前后进行拦截,而不能在属性前后进行拦截。

2、Spring支持四种拦截类型:目标方法调用前(before),目标方法调用后(after),目标方法调用前后(around),以及目标方法抛出异常(throw)。

3、前置拦截的类必须实现MethodBeforeAdvice接口,实现其中的before方法。

4、后置拦截的类必须实现AfterReturningAdvice接口,实现其中的afterReturning方法。

5、前后拦截的类必须实现MethodInterceptor接口,实现其中的invoke方法。前后拦截是唯一可以控制目标方法是否被真正调用的拦截类型,也可以控制返回对象。而前置拦截或后置拦截不能控制,它们不能印象目标方法的调用和返回。

但是以上的拦截的问题在于,不能对于特定方法进行拦截,而只能对某个类的全部方法作拦截。所以下面引入了两个新概念:“切入点”和“引入通知”。

6、”切入点“的定义相当于更加细化地规定了哪些方法被哪些拦截器所拦截,而并非所有的方法都被所有的拦截器所拦截。在ProxyFactoryBean的属性中,interceptorNames属性的对象也由拦截(Advice)变成了引入通知(Advisor),正是在Advisor中详细定义了切入点(PointCut)和拦截(Advice)的对应关系,比如常见的基于名字的切入点匹配(NameMatchMethodPointcutAdvisor类)和基于正则表达式的切入点匹配(RegExpPointcutAdvisor类)。这些切入点都属于”静态切入点“,因为他们只在代理创建的时候被创建一次,而不是每次运行都创建。

下面我们进行实例的开发

首先创建业务接口:

package AdvisorTest;

public interface Shopping ...{

public String buySomething(String type);

public String buyAnything(String type);

public void testException();

}

下面是业务实现类,我们的通知就是以这些实现类作为切面,在业务方法前后加入我们的通知代码

package AdvisorTest;

public class ShoppingImpl implements Shopping ...{

    private Customer customer;

    public Customer getCustomer() ...{

        return customer;

    }

    public void setCustomer(Customer customer) ...{

        this.customer = customer;

    }

    public String buySomething(String type) ...{

        System.out.println(this.getCustomer().getName()+" bye "+type+" success");

        return null;

    }

   

    public String buyAnything(String type) ...{

       System.out.println(this.getCustomer().getName()+" bye "+type+" success");

       return null;

     }

    public void testException()...{

        throw new ClassCastException();

    }

}

(1)前置通知

        配置了前置通知的bean,在执行业务方法前,均会执行前置拦截器的before方法

package AdvisorTest;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

//前置通知

public class WelcomeAdvice implements MethodBeforeAdvice ...{

    public void before(Method method, Object[] args, Object obj)

            throws Throwable ...{

        String type=(String)args[0];

        System.out.println("Hello welcome to bye "+type);

    }

}

(2)后置通知

配置了前置通知的bean,在执行业务方法前,均会执行前置拦截器的afterReturnning方法 package AdvisorTest;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

import org.springframework.aop.MethodBeforeAdvice;

//后置通知

public class ThankYouAdvice implements AfterReturningAdvice ...{

    public void afterReturning(Object obj, Method method, Object[] arg1,

            Object arg2) throws Throwable ...{

       

         String type=(String)arg1[0];

         System.out.println("Hello Thankyou to bye "+type);

    }

   

}

(3)环绕通知

配置了前置通知的bean,在执行业务方法前后,均会执行前置拦截器的invoke方法

需要注意的是必须调用目标方法,如不调用,目标方法将不被执行

package AdvisorTest;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

public class MethodAdvisor implements MethodInterceptor ...{

    public Object invoke(MethodInvocation invocation) throws Throwable ...{

        String str=(String)invocation.getArguments()[0];

        System.out.println("this is before"+str+" in MethodInterceptor");

        Object obj=invocation.proceed(); //调用目标方法,如不调用,目标方法将不被执行

        System.out.println("this is after"+str+" in MethodInterceptor");

        return null;

    }

}

(4)异常通知

ThrowsAdvice是一个标示接口,我们可以在类中定义一个或多个,来捕获定义异常通知的bean抛出的异常,并在抛出异常前执行相应的方法

public void afterThrowing(Throwable throwa){}或者

public void afterThrowing(Method method,Object[] args,Object target,Throwable throwable){

package AdvisorTest;

import org.springframework.aop.ThrowsAdvice;

public class ExceptionAdvisor implements ThrowsAdvice ...{

public void afterThrowing(ClassCastException e)...{

      System.out.println("this is from exceptionAdvisor");

}

}

配置文件

<?xml version="1.0" encoding="UTF-8"?>

ttp://www.springframework.org/dtd/spring-beans.dtd" target="_blank">http://www.springframework.org/dtd/spring-beans.dtd" >

  

     gaoxiang

  

   

     26

  

  

    

  

    AdvisorTest.Shopping

   

   

      welcomeAdvice

   

    AdvisorTest.Shopping

   

   

      thankyouAdvice

   

    AdvisorTest.Shopping

   

   

      methodAdvice

   

    AdvisorTest.Shopping

   

   

      exceptionAdvice

   

测试代码:

package AdvisorTest;

import java.io.File;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.xml.XmlBeanFactory;

import org.springframework.core.io.FileSystemResource;

public class TestAdvisor ...{

    public static void main(String[] args) ...{

        String filePath=System.getProperty("user.dir")+File.separator+"AdvisorTest"+File.separator+"hello.xml";

       

        BeanFactory factory=new XmlBeanFactory(new FileSystemResource(filePath));

       

        Shopping shopping=null;

        System.out.println("不使用任何通知");

        shopping=(Shopping)factory.getBean("shoppingImpl");

        shopping.buySomething("something");

        shopping.buyAnything("anything");

       

        System.out.println("使用前置通知");

        shopping=(Shopping)factory.getBean("welcomeAdviceShop");

        shopping.buySomething("something");

        shopping.buyAnything("anything");

       

        System.out.println("使用后置通知");

        shopping=(Shopping)factory.getBean("thankyouAdviceShop");

        shopping.buySomething("something");

        shopping.buyAnything("anything");

       

        System.out.println("使用环绕通知");

        shopping=(Shopping)factory.getBean("methodAdviceShop");

        shopping.buySomething("something");

        shopping.buyAnything("anything");

       

        System.out.println("使用异常通知");

        shopping=(Shopping)factory.getBean("exceptionAdviceShop");

        shopping.testException();

   

    }

}

运行结果一目了然:

不使用任何通知

gaoxiang bye something success

gaoxiang bye anything success

使用前置通知

Hello welcome to bye something

gaoxiang bye something success

Hello welcome to bye anything

gaoxiang bye anything success

使用后置通知

gaoxiang bye something success

Hello Thankyou to bye something

gaoxiang bye anything success

Hello Thankyou to bye anything

使用环绕通知

this is beforesomething in MethodInterceptor

gaoxiang bye something success

this is aftersomething in MethodInterceptor

this is beforeanything in MethodInterceptor

gaoxiang bye anything success

this is afteranything in MethodInterceptor

使用异常通知

this is from exceptionAdvisor

目录
相关文章
|
5月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
618 0
|
9月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
1374 13
|
4月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
4月前
|
缓存 监控 Java
《深入理解Spring》拦截器(Interceptor)——请求处理的艺术
Spring拦截器是Web开发中实现横切关注点的核心组件,基于AOP思想,可在请求处理前后执行日志记录、身份验证、权限控制等通用逻辑。相比Servlet过滤器,拦截器更贴近Spring容器,能访问Bean和上下文,适用于Controller级精细控制。通过实现`HandlerInterceptor`接口的`preHandle`、`postHandle`和`afterCompletion`方法,可灵活控制请求流程。结合配置类注册并设置路径匹配与执行顺序,实现高效复用与维护。常用于认证鉴权、性能监控、统一异常处理等场景,提升应用安全性与可维护性。
|
6月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
6月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
存储 人工智能 Java
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
|
7月前
|
人工智能 安全 Java
Spring Boot 过滤器 拦截器 监听器
本文介绍了Spring Boot中的过滤器、拦截器和监听器的实现与应用。通过Filter接口和FilterRegistrationBean类,开发者可实现对请求和响应的数据过滤;使用HandlerInterceptor接口,可在控制器方法执行前后进行处理;利用各种监听器接口(如ServletRequestListener、HttpSessionListener等),可监听Web应用中的事件并作出响应。文章还提供了多个代码示例,帮助读者理解如何创建和配置这些组件,适用于构建更高效、安全和可控的Spring Boot应用程序。
751 0
|
11月前
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
495 0