我们可以在 Spring 项目中通过 XML 配置,对切面(Aspect 或 Advisor)、切点(PointCut)以及通知(Advice)进行定义和管理,以实现基于 AspectJ 的 AOP 开发。
Spring 提供了基于 XML 的 AOP 支持,并提供了一个名为“aop”的命名空间,该命名空间提供了一个 <aop:config> 元素。
首先,我们需要在 XML 配置文件中导入 Spring aop 命名空间的约束,如下所示。
下面我们通过一个示例来演示下 Spring 集成 AspectJ 基于 XML 实现 AOP 开发。
1. 新建一个名为 my-spring-asepctj-demo 的 Java 项目,并将以下依赖 Jar 包导入到该项目中。
2. 在 net.biancheng.c.dao 包下,创建一个名为 OrderDao 的接口,代码如下。
3. 在 net.biancheng.c.dao.impl 包下,创建 OrderDao 的实现类 OrderDaoImpl,代码如下。
package net.biancheng.c.dao.impl; import net.biancheng.c.dao.OrderDao; public class OrderDaoImpl implements OrderDao { @Override public void add() { System.out.println("正在执行 OrderDao 中的 add() 方法"); } @Override public void delete() { System.out.println("正在执行 OrderDao 中的 delete() 方法"); } @Override public int modify() { System.out.println("正在执行 OrderDao 中的 modify() 方法"); return 1; } @Override public void get() { //异常 int a = 10 / 0; System.out.println("正在执行 OrderDao 中的 get() 方法"); } }
4. 在 net.biancheng.c 包下,创建一个名为 MyOrderAspect 的类,代码如下。
package net.biancheng.c; import org.aspectj.lang.ProceedingJoinPoint; public class MyOrderAspect { public void before() { System.out.println("前置增强……"); } public void after() { System.out.println("最终增强……"); } public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕增强---前……"); proceedingJoinPoint.proceed(); System.out.println("环绕增强---后……"); } public void afterThrow(Throwable exception) { System.out.println("异常增强…… 异常信息为:" + exception.getMessage()); } public void afterReturning(Object returnValue) { System.out.println("后置返回增强…… 方法返回值为:" + returnValue); } }
5. 在 src 目录下创建一个 Spring 配置文件 Beans2.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:context="http://www.springframework.org/schema/context" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--定义 Bean--> <bean id="orderDao" class="net.biancheng.c.dao.impl.OrderDaoImpl"></bean> <!--定义切面--> <bean id="myOrderAspect" class="net.biancheng.c.MyOrderAspect"></bean> <aop:config> <aop:pointcut id="beforePointCut" expression="execution(* net.biancheng.c.dao.OrderDao.add(..))"/> <aop:pointcut id="throwPointCut" expression="execution(* net.biancheng.c.dao.OrderDao.get(..))"/> <aop:pointcut id="afterReturnPointCut" expression="execution(* net.biancheng.c.dao.OrderDao.modify(..))"/> <aop:pointcut id="afterPointCut" expression="execution(* net.biancheng.c.dao.OrderDao.*(..))"/> <aop:aspect ref="myOrderAspect"> <!--前置增强--> <aop:before method="before" pointcut-ref="beforePointCut"></aop:before> <!--后置返回增强--> <aop:after-returning method="afterReturning" pointcut-ref="afterReturnPointCut" returning="returnValue"></aop:after-returning> <!--异常通知--> <aop:after-throwing method="afterThrow" pointcut-ref="throwPointCut" throwing="exception"></aop:after-throwing> <!--最终通知--> <aop:after method="after" pointcut-ref="afterPointCut"></aop:after> <!--环绕通知--> <aop:around method="around" pointcut-ref="beforePointCut"></aop:around> </aop:aspect> </aop:config> </beans>