本文介绍通过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为辅。
来源:https://www.cnblogs.com/hellowhy/p/9721258.html