• Spring AOP(三)--XML方式实现


    本文介绍通过XML方式实现Spring AOP,在上一篇中已经介绍了通过注解+java配置的方式,这篇文章主要是看XML中怎么配置,直接上代码了:

    一、创建一个连接点

    1⃣️定义接口

    注意⚠️:可以定义接口,也可以不定义,定义接口时使用jdk动态代理,不定义接口时使用cglib动态代理;

    1 //定义一个接口
    2 public interface CoderProjectService {
    3     public void getProjectInfo(CoderProject coderProject);
    4 }

    2⃣️接口实现类

     1 //创建一个类来处理业务逻辑,作为要织入切面中的被代理对象
     2 public class CoderProjectServiceImpl implements CoderProjectService {
     3 
     4     @Override
     5     public void getProjectInfo(CoderProject coderProject) {
     6         System.out.println("项目名称:" + coderProject.getProjectName() + "--项目版本号:" + coderProject.getProjectVersion()
     7                 + "--项目描述:" + coderProject.getProjectDesc());
     8     }
     9 
    10 }

    因为我要配置引入功能,所以顺便定义要引入的接口及实现类

    3⃣️创建引入接口

    1 /*
    2  * 定义一个新接口,用来做一些验证
    3  */
    4 public interface CheckExist {
    5     public boolean checkIsEmpty(CoderProject project);
    6 }

    4⃣️引入接口实现类

     1 /*
     2  * 定义一个类,增加一些验证逻辑,对被代理对象逻辑进行增强或完善
     3  */
     4 public class CheckExistImp implements CheckExist {
     5 
     6     @Override
     7     public boolean checkIsEmpty(CoderProject project) {
     8         return project != null;
     9     }
    10 
    11 }

    二、创建一个切面

     1 /*
     2  * 定义一个切面,没有任何注解,需要在XML中进行配置
     3  */
     4 public class XmlAspect {
     5 
     6     // 引入增强类
     7     public CheckExistImp checkExistImp;
     8 
     9     public void before(CoderProject pro) {
    10         System.out.println("项目名称: " + pro.getProjectName() + "before...");
    11     }
    12 
    13     public void around(ProceedingJoinPoint pjp) {
    14         System.out.println("around before...");
    15         try {
    16             pjp.proceed();
    17         } catch (Throwable e) {
    18             e.printStackTrace();
    19         }
    20         System.out.println("around after...");
    21     }
    22 
    23     public void after() {
    24         System.out.println("after...");
    25     }
    26 
    27     public void afterThrowing() {
    28         System.out.println("afterThrowing...");
    29     }
    30 
    31     public void afterReturning() {
    32         System.out.println("afterReturning...");
    33     }
    34 }

    这个切面就是一个简单的类,不过提供了四种通知的方法,并且前置通知含有参数,同时也将引入类作为属性添加进来,之前的所有注解都会在XML文件中配置。

    三、配置spring-aop-xml.xml配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     5         http://www.springframework.org/schema/beans/spring-beans.xsd 
     6         http://www.springframework.org/schema/aop 
     7         http://www.springframework.org/schema/aop/spring-aop.xsd">
     8     <!--定义切面bean -->
     9     <bean id="xmlAspect" class="com.hyc.aop.xml.XmlAspect"></bean>
    10     <!-- 定义被代理对象bean -->
    11     <bean id="coderProjectService" class="com.hyc.aop.xml.CoderProjectServiceImpl"></bean>
    12     <!-- 定义切面的配置:注解 -->
    13     <aop:config>
    14         <aop:aspect ref="xmlAspect">
    15             <!--定义一个切点 -->
    16             <aop:pointcut id="getProjectInfo"  expression="execution(* com.hyc.aop.xml.CoderProjectServiceImpl.getProjectInfo(..))" />
    17             <!-- 定义四类通知-->
    18             <aop:before method="before" pointcut="execution(* com.hyc.aop.xml.CoderProjectServiceImpl.getProjectInfo(..))  and args(pro))"/>
    19             <aop:after method="after" pointcut-ref="getProjectInfo"/>
    20             <aop:after-returning method="afterReturning" pointcut-ref="getProjectInfo"/>
    21             <aop:after-throwing method="afterThrowing" pointcut-ref="getProjectInfo"/>
    22             <!-- 定义环绕通知 -->
    23             <aop:around method="around" pointcut-ref="getProjectInfo"/>
    24             <!--定义增强类  -->
    25             <aop:declare-parents types-matching="com.hyc.aop.xml.CoderProjectServiceImpl+" implement-interface="com.hyc.aop.xml.CheckExist" default-impl="com.hyc.aop.xml.CheckExistImp"/>
    26         </aop:aspect>
    27     </aop:config>
    28     
    29     <!-- 定义一个project bean,用来传给接入点方法 -->
    30     <bean id="project" class="com.hyc.pojo.CoderProject">
    31         <property name="id" value="1" />
    32         <property name="projectName" value="云管理平台" />
    33         <property name="projectVersion" value="V1.0" />
    34         <property name="projectDesc" value="云存储管理平台" />
    35     </bean>
    36 </beans>

    注意⚠️:在使用aop配置之前,要先引入相关的命名空间,如上面代码中的红色加粗部分。

    其他的配置及含义都在注释中有接受,不再赘述;

    四、创建测试方法

     1     @Test
     2     public void testAopByXml() {
     3         // 动态生成切面
     4         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring-aop-xml.xml");
     5         // 获取被代理对象
     6         CoderProjectService coderProjectService = (CoderProjectService) context.getBean("coderProjectService");
     7         // 获取项目类(参数)
     8         CoderProject project = (CoderProject) context.getBean("project");
     9         // 获取增强类(将被代理对象强制转化成增强类)
    10         CheckExist cd = (CheckExist) coderProjectService;
    11         if (cd.checkIsEmpty(project)) {
    12             coderProjectService.getProjectInfo(project);
    13         } else {
    14             System.out.println("被代理对象不能为空");
    15         }
    16     }

    测试结果如下:

    1 项目名称: 云管理平台before...
    2 around before...
    3 项目名称:云管理平台--项目版本号:V1.0--项目描述:云存储管理平台
    4 around after...
    5 afterReturning...
    6 after...

    可以看到按照Sprinf AOP规定的流程执行了方法,但是就如在上一篇文章中提到的,使用XML方式时,around的before方法会在before方法之后执行。

    其实从实现过程就能看出来,注解方式比XML要简单,因为XML要配置很多东西,而且容易出错,所以一般来说以注解为主,XML为辅。

  • 相关阅读:
    火狐推荐几个实用的插件
    Ubuntu下安装可视化SVN客户端Rabbitvcs
    thunderbird中如何设置QQ邮箱
    Ubuntu 10.04里安装强大抓图工具Shutter
    cannot start compilation;the output path is not specified for module specify the output path in the project structure dialog
    jrebel+idea 进行热部署配置
    jeecg数据库切换至mysql8.0方式
    com.alibaba.druid.pool.DruidDataSource 使用druid数据源 No supported DataSource type found
    租户的基本信息表
    kettle系列-我的开源kettle调度、管理平台[kettle-manager]介绍
  • 原文地址:https://www.cnblogs.com/hellowhy/p/9721258.html
Copyright © 2020-2023  润新知