Spring AOP官方文档学习笔记(三)之基于xml的Spring AOP

1.声明schema,导入命名空间

(1)如果我们想要使用基于xml的spring aop,那么,第一步,我们需要在xml配置文件中声明spring aop schema,导入命名空间,如下这是一个标准的模板

<?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"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <!-- //... -->

</beans>

(2)在xml配置文件中,所有的切面以及通知等都必须放置于<aop:config>标签内

2.声明一个切面

//定义一个切面类Logger,在其中声明一个前置通知
public class Logger {

    public void beforePrint() {
        System.out.println("before...");
    }
}

<!-- xml配置文件 -->
<beans ....>
    <!-- 将切面类注册为spring的一个bean -->
    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>

    <aop:config>
        <!-- 使用<aop:aspect>标签,来定义一个切面,其中id的值需唯一,ref用来引用切面类 -->
        <aop:aspect id="aspect" ref="logger">
            <!-- 在<aop:aspect>标签内部,我们可以定义5种通知,在这里使用<aop:before>标签来定义一个前置通知,其中method指定通知方法,它只能是Logger这个切面类中的方法,pointcut指定切入点表达式 -->
            <aop:before method="beforePrint" pointcut="execution(* cn.example.spring.boke.ExampleA.*(..))"></aop:before>
        </aop:aspect>
    </aop:config>

</beans>

3.声明一个切入点

<beans ....>

    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>

    <aop:config>
        <!-- 使用<aop:pointcut>标签来定义一个切入点,其中id的值唯一,expression即为切入点表达式 -->
        <!-- 之后,在通知标签内部,使用pointcut-ref来引用这个切入点 -->
        <aop:pointcut id="common" expression="execution(* cn.example.spring.boke.ExampleA.*(..))"/>

        <!-- 在基于xml的切入点表达式中 &&, || 以及 ! 分别被替换为了 and, or 与 not,如下面这个例子 -->
        <aop:pointcut id="mix" expression="execution(public * *(..)) and @args(org.springframework.stereotype.Component)"/>

        <aop:aspect id="aspect" ref="logger">
            <aop:before method="beforePrint" pointcut-ref="common"></aop:before>
        </aop:aspect>
    </aop:config>
</beans>

4.声明一个通知

//切面类
public class Logger {
    public void beforePrint() {
        System.out.println("before...");
    }

    public void afterReturningPrint(Object returnVal) {
        System.out.println(returnVal);
        System.out.println("afterReturning...");
    }

    public void afterThrowingPrint(Throwable throwable) {
        System.out.println(throwable);
        System.out.println("afterThrowing...");
    }

    public void afterPrint() {
        System.out.println("after...");
    }

    public void aroundPrint(ProceedingJoinPoint joinPoint) {
        try {
            System.out.println("before...");
            joinPoint.proceed();
            System.out.println("after...");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            System.out.println("finally...");
        }
    }
}

<aop:config>
    <aop:pointcut id="common" expression="execution(* cn.example.spring.boke.ExampleA.*(..))"/>

    <aop:aspect id="aspect" ref="logger">
        <!-- 使用<aop:before>声明前置通知 -->
        <aop:before method="beforePrint" pointcut-ref="common"></aop:before>

        <!-- 使用<aop:after-returning>声明返回通知,其中使用returning属性来声明获取切入点执行后的返回值,与前面基于注解的示例相同 -->
        <aop:after-returning method="afterReturningPrint" pointcut-ref="common" returning="returnVal"></aop:after-returning>

        <!-- 使用<aop:after-throwing>声明异常通知,其中使用throwing属性来声明获取切入点执行异常后所抛出的异常,与前面基于注解的示例相同 -->
        <aop:after-throwing method="afterThrowingPrint" pointcut-ref="common" throwing="throwable"></aop:after-throwing>

        <!-- 使用<aop:after>声明后置通知 -->
        <aop:after method="afterPrint" pointcut-ref="common"></aop:after>
  
        <!-- 使用<aop:around>声明环绕通知,具体的注意事项与前面基于注解的示例相同 -->
        <aop:around method="aroundPrint" pointcut-ref="common"></aop:around>
    </aop:aspect>
</aop:config>

5.优先级

<beans ....>

    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>

    <bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>

    <aop:config>
        <aop:pointcut id="common" expression="execution(* cn.example.spring.boke.ExampleA.*(..))"/>
        <!-- 可使用<aop:aspect/>标签中的order属性来声明不同切面类的优先级 -->
        <aop:aspect id="aspect" ref="logger" order="1">
            <!-- 在同一切面类中,不同切面的优先级与切面声明的顺序有关,如下由于<aop:before/>标签声明于<aop:around/>标签之前,因此before的优先级高于around -->
            <aop:before method="beforePrint" pointcut-ref="common"></aop:before>

            <aop:around method="aroundPrint" pointcut-ref="common"></aop:around>
        </aop:aspect>
    </aop:config>

</beans>

6.声明一个引介

public class ExampleA{

}

//希望向ExampleA中添加方法doSomething()
public interface Extention {
    void doSomething();
}

//doSomething()方法默认的实现
public class ExtentionImpl implements Extention{

    @Override
    public void doSomething() {
        System.out.println("doSomething...");
    }
}

<beans ....>

    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>

    <bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>

    <aop:config>

        <aop:aspect id="aspect" ref="logger">
            <!-- 在<aop:aspect/>标签中,使用<aop:declare-parents/>标签便可声明一个引介,其中types-matching属性值对应@DeclareParents注解中的value属性值,default-impl属性值对应@DeclareParents注解中的defaultImpl属性值,implement-interface表明父类型,与基于注解的配置一致 -->
            <aop:declare-parents types-matching="cn.example.spring.boke.*" implement-interface="cn.example.spring.boke.Extention" default-impl="cn.example.spring.boke.ExtentionImpl"></aop:declare-parents>
        </aop:aspect>
    </aop:config>

</beans>

//使用引介,与基于注解的配置一致
Extention exampleA = (Extention)ctx.getBean("exampleA");

7.Advisors

(1) 除了使用<aop:aspect/>标签外,我们还可以使用<aop:advisor/>标签来声明一个切面,不过使用<aop:advisor/>时,其所指向的bean必须要实现对应的Advice接口,如下

//若要定义前置通知,则必须实现MethodBeforeAdvice接口,其他相应的通知也有对应的接口
public class Logger implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("advisor before...");
    }
}

<beans ....>

    <bean id="logger" class="cn.example.spring.boke.Logger"></bean>

    <bean id="exampleA" class="cn.example.spring.boke.ExampleA"></bean>

    <aop:config>
        <aop:pointcut id="common" expression="execution(* cn.example.spring.boke.ExampleA.*(..))"/>
        <!-- 使用<aop:advisor/>标签来定义一个切面,与前面的<aop:aspect/>标签相比,不需要在其内部声明具体的通知标签了,在底层原理上,<aop:advisor/>与<aop:aspect/>是相似的,只是<aop:advisor/>的使用方式变了而已,且该标签一般专用于事物管理上 -->
        <aop:advisor advice-ref="logger" pointcut-ref="common"></aop:advisor>
    </aop:config>

</beans>

原文链接:https://www.cnblogs.com/shame11/p/17325395.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring AOP官方文档学习笔记(三)之基于xml的Spring AOP - Python技术站

(0)
上一篇 2023年5月3日
下一篇 2023年5月4日

相关文章

  • 探究JavaScript函数式编程的乐趣

    探究JavaScript函数式编程的乐趣 函数式编程是一种以函数为基础,将计算看作数学函数的风格。这种编程方式通常被指定为声明式编程,因为它主要使用函数声明来刻画程序结果。本文将介绍JavaScript中的函数式编程的乐趣,并引入两个示例以解释其用途。 什么是函数式编程? 函数式编程是一种流行的JavaScript编程范式。它的目标是使用函数来处理数据,而不…

    Java 2023年5月26日
    00
  • java从list中取出对象并获得其属性值的方法

    下面是详细讲解Java从List中取出对象并获得其属性值的方法的完整攻略。 1. 获取List中的对象 我们需要先将对象存储在List集合中,所以我们应该首先创建一个对象,并将它添加到List中。 示例1: 假设我们要从List中取出名字为“Tom”的Person对象中的年龄,我们可以先创建一个Person对象,并将其添加到List中。代码如下: List&…

    Java 2023年5月26日
    00
  • JAVA文件读写操作详解

    JAVA文件读写操作详解 什么是文件读写操作 文件读写操作是指对于指定的文件,通过程序的方式读取其中的数据或者将程序中的数据写入到文件中。文件读写操作是一个底层的技术,基本上所有的软件开发都会用到这个技术。 JAVA文件读写操作的常用类 在JAVA中,文件读写操作主要涉及到以下几个类: File类:代表文件和目录的抽象表示。通过对File类的操作,可以创建、…

    Java 2023年5月20日
    00
  • springmvc Rest风格介绍及实现代码示例

    SpringMVC Rest风格介绍及实现代码示例 在Web开发中,REST(Representational State Transfer)是一种架构风格,它提供了一种简单的方式来创建Web服务。SpringMVC框架支持RESTful Web服务的开发,本文将详细介绍SpringMVC Rest风格的实现及代码示例。 Rest风格介绍 REST是一种基于…

    Java 2023年5月17日
    00
  • Java SimpleDateFormat线程安全问题原理详解

    Java SimpleDateFormat线程安全问题原理详解 简介 SimpleDateFormat 是 Java 中处理日期格式化的常用类,常用来将 Date 类型转换成特定格式的字符串。然而,SimpleDateFormat 是非线程安全的,当多个线程同时访问同一个 SimpleDateFormat 实例时,就会出现线程安全问题。本文将通过分析 Sim…

    Java 2023年6月1日
    00
  • Apache Hudi结合Flink的亿级数据入湖实践解析

    下面我来详细讲解一下Apache Hudi结合Flink的亿级数据入湖实践解析的完整攻略。 概述 本文主要介绍如何使用Apache Hudi和Flink实现亿级数据的入湖操作。Hudi是一个可靠的增量数据处理框架,适用于在Apache Spark等大数据处理框架上进行大数据增量计算。而Flink则是一个分布式流处理框架,具有高吞吐量和低延迟的特点。将两者结合…

    Java 2023年5月20日
    00
  • Spring Security基于散列加密方案实现自动登录功能

    下面是Spring Security实现自动登录的攻略: 1. 基础知识 在实现Spring Security的自动登录功能之前,需要先了解一些基本的概念和技术: 1.1 散列加密 散列加密是将明文转换成一串不可逆的字符串的过程。在Spring Security中,常使用的散列算法有MD5、SHA-1、SHA-256等。 1.2 Cookie Cookie是…

    Java 2023年5月20日
    00
  • Spring-Security对HTTP相应头的安全支持方式

    Spring Security 提供了许多机制来增强 Web 应用程序的安全性。其中一个是它支持将标准 HTTP 相应头设置为提高 Web 应用程序的安全性。这包括常见的头,如 X-Content-Type-Options、X-XSS-Protection、X-Frame-Options、Strict-Transport-Security 等。在本文中,我们…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部