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

一、创建一个连接点

1⃣️定义接口

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

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

2⃣️接口实现类

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

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

3⃣️创建引入接口

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

4⃣️引入接口实现类

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

二、创建一个切面

 /*
* 定义一个切面,没有任何注解,需要在XML中进行配置
*/
public class XmlAspect { // 引入增强类
public CheckExistImp checkExistImp; public void before(CoderProject pro) {
System.out.println("项目名称: " + pro.getProjectName() + "before...");
} public void around(ProceedingJoinPoint pjp) {
System.out.println("around before...");
try {
pjp.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("around after...");
} public void after() {
System.out.println("after...");
} public void afterThrowing() {
System.out.println("afterThrowing...");
} public void afterReturning() {
System.out.println("afterReturning...");
}
}

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

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

 <?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--定义切面bean -->
<bean id="xmlAspect" class="com.hyc.aop.xml.XmlAspect"></bean>
<!-- 定义被代理对象bean -->
<bean id="coderProjectService" class="com.hyc.aop.xml.CoderProjectServiceImpl"></bean>
<!-- 定义切面的配置:注解 -->
<aop:config>
<aop:aspect ref="xmlAspect">
<!--定义一个切点 -->
<aop:pointcut id="getProjectInfo" expression="execution(* com.hyc.aop.xml.CoderProjectServiceImpl.getProjectInfo(..))" />
<!-- 定义四类通知-->
<aop:before method="before" pointcut="execution(* com.hyc.aop.xml.CoderProjectServiceImpl.getProjectInfo(..)) and args(pro))"/>
<aop:after method="after" pointcut-ref="getProjectInfo"/>
<aop:after-returning method="afterReturning" pointcut-ref="getProjectInfo"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="getProjectInfo"/>
<!-- 定义环绕通知 -->
<aop:around method="around" pointcut-ref="getProjectInfo"/>
<!--定义增强类 -->
<aop:declare-parents types-matching="com.hyc.aop.xml.CoderProjectServiceImpl+" implement-interface="com.hyc.aop.xml.CheckExist" default-impl="com.hyc.aop.xml.CheckExistImp"/>
</aop:aspect>
</aop:config> <!-- 定义一个project bean,用来传给接入点方法 -->
<bean id="project" class="com.hyc.pojo.CoderProject">
<property name="id" value="1" />
<property name="projectName" value="云管理平台" />
<property name="projectVersion" value="V1.0" />
<property name="projectDesc" value="云存储管理平台" />
</bean>
</beans>

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

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

四、创建测试方法

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

测试结果如下:

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

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

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

最新文章

  1. 步步深入:MySQL架构总览-&gt;查询执行流程-&gt;SQL解析顺序
  2. 瀑布流StaggeredGridView 下拉刷新
  3. Ubuntu 12.04(32位)安装Oracle 11g(32位)
  4. Android Bluetooth Stack: Bluedroid(五岁以下儿童):The analysis of A2DP Source
  5. 超详细LAMP环境搭建
  6. Inno Setup入门(十九)&mdash;&mdash;Inno Setup类参考(5)
  7. Centos 6修复/boot目录及fstab等系统文件
  8. 简单的线性规划-scipy
  9. BZOJ 2683: 简单题(CDQ分治 + 树状数组)
  10. Self-organizing Maps及其改进算法Neural gas聚类在异常进程事件识别可行性初探
  11. 【sqli-labs】Less18~Less22
  12. Sublime Text 显示韩文和文件编码
  13. jquery.cookie用法及其注意点
  14. Zabbix故障总结(持续更新)
  15. ss的使用配置(电脑、手机FQ)
  16. pthread之线程堆栈
  17. JDBC的驱动是如何加载的
  18. exml自动加载图片
  19. tyvj 1038 忠诚 区间最小值 线段树或者rmq
  20. E0443类模板 &quot;std::unordered_set&quot; 的参数太多

热门文章

  1. tomcat JAVA_OPTS设置
  2. 理解云计算三种服务模式——IaaS、PaaS和SaaS
  3. 通过key_len分析联合索引的使用
  4. while语句结构(for循环)
  5. [JZOJ5232] 【NOIP2017模拟A组模拟8.5】带权排序
  6. HZOI20190816模拟23 mine/water/gcd
  7. vue基础知识总结
  8. 解决git每次输入密码,设置gitlab、github默认push的用户名和密码
  9. Python import用法以及与from...import的区别
  10. webservice技术--服务器端