首页 > 其他分享 >Spring AOP官方文档学习笔记(三)之基于xml的Spring AOP

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

时间:2023-05-04 11:24:17浏览次数:40  
标签:xml -- Spring AOP System 标签 println public out

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>

标签:xml,--,Spring,AOP,System,标签,println,public,out
From: https://www.cnblogs.com/shame11/p/17325395.html

相关文章

  • SpringBoot项目部署在外置Tomcat正常启动,但项目没有被加载的问题
    最近打算部署个SpringBoot项目到外置Tomcat运行,但是发现tomcat启动成功,访问却一直404,刚开始以为是Tomcat的问题,就一直在改Tomcat配置。最后发现tomcat启动时根本就没加载到项目,因为控制台没有打印"SpringBoot"的项目标志经过一番百度查找,最后发现是因为项目启动类没有继承Spring......
  • SpringMVC03_校验和拦截器
    以下代码全过程在上篇一、SpringMVC校验​ 举一个简单的例子,在登陆时我们要检验用户名是否输入、密码是否合法。(一)引入依赖框架​ 在Spring-MVC中我们需要添加Hibernate的Validator检验框架,注意下面的版本号,615Final对应的应该是importjavax.validation.constraints......
  • SpringSecurity简介
    ------------恢复内容开始------------SpringSecurity简介SpringSecurity是spring家族中的一个安全框架,相比与另外一个安全框架Shiro,它提供了更丰富的功能,社区资源也比Shiro丰富一般来说中大型的项目都是使用springsecurity来做安全框架,小项目有Shiro的比较多,因为相比与Spri......
  • 从Spring源码分析@Autowired依赖注入实现原理
    在平常项目开发中,使用@Autowired注解进行字段注入很常用,本篇就通过Spring源码,重点分析这种方式实现依赖注入的过程。本篇Spring源码版本为5.1.7.RELEASE。在源码中,关键类是AbstractAutowireCapableBeanFactory,这个类继承AbstractBeanFactory,所以在Spring上下文启动......
  • Spring整合Junit
    Spring整合Junit整合Junit与整合Druid和MyBatis差异比较大,为什么呢?Junit是一个搞单元测试用的工具,它不是我们程序的主体,也不会参加最终程序的运行,从作用上来说就和之前的东西不一样,它不是做功能的,看做是一个辅助工具就可以了。1、环境准备这块环境,大家可以直接使用Spring与Myb......
  • 基于springcloud实现的医院信息系统
    访问【WRITE-BUG数字空间】_[内附完整源码和文档]医疗信息就诊系统,系统主要功能按照数据流量、流向及处理过程分为临床诊疗、药品管理、财务管理、患者管理。诊疗活动由各工作站配合完成,并将临床信息进行整理、处理、汇总、统计、分析等。本系统包括以下工作站:门诊医生工作站、药房......
  • 记录一件很神奇的类型转换问题(springboot项目+echarts)
    今天博主在应付学校的实验,想要使用echarts绘制一张很简单的条形图(博主是初学者),如下(时间还未作排序) 对于横轴,我封装了一个dateList,这个datelist是用java,将数据库中date类型的数据,提取其年月拼装而成的,代码如下:Stringdate=String.valueOf(art.getArticleCreateTime().getYea......
  • java基于springboot+vue非前后端分离的网上商城购物系统、在线商城管理系统,附源码+数
    1、项目介绍java基于springboot+vue非前后端分离的网上商城购物系统、在线商城管理系统,实现管理员:首页、个人中心、用户管理、商品分类管理、商品信息管理、订单评价管理、系统管理、订单管理,用户;首页、个人中心、订单评价管理、我的收藏管理、订单管理,前台首页;首页、商品信息、......
  • SpringCloud gateway谓词
    1、AfterRoutePredicateFactoryAfter路由谓词工厂接受一个参数,一个日期时间(它是一个javaZonedDateTime)。此谓词匹配在指定日期时间之后发生的请求。例如:spring:cloud:gateway:enabled:trueroutes:-id:Goods-Server#路由id,唯一标识......
  • java.Tang.CassNotFoundException javax.xmL.bind.DatatypeConverter
    报错如下图所示:故障原因:JAXBAPI是javaEE的API,因此在javaSE9.0中不再包含这个Jar包。java9中引入了模块的概念,默认情况下,JavaSE中将不再包含javaEE的Jar包而在java6/7/8时关于这个API都是捆绑在一起的解决方案:降低JDK版本到JDK8手动加入这些依赖......