我们可以在 Spring 项目中通过 XML 配置,对切面(Aspect 或 Advisor)、切点(PointCut)以及通知(Advice)进行定义和管理,以实现基于 AspectJ 的 AOP 开发。
Spring 提供了基于 XML 的 AOP 支持,并提供了一个名为“aop”的命名空间,该命名空间提供了一个 <aop:config> 元素。
- 在 Spring 配置中,所有的切面信息(切面、切点、通知)都必须定义在 <aop:config> 元素中;
- 在 Spring 配置中,可以使用多个 <aop:config>。
- 每一个 <aop:config> 元素内可以包含 3 个子元素: pointcut、advisor 和 aspect ,这些子元素必须按照这个顺序进行声明。
引入 aop 命名空间
首先,我们需要在 XML 配置文件中导入 Spring aop 命名空间的约束,如下所示。
示例
下面我们通过一个示例来演示下 Spring 集成 AspectJ 基于 XML 实现 AOP 开发。
1. 新建一个名为 my-spring-asepctj-demo 的 Java 项目,并将以下依赖 Jar 包导入到该项目中。
- commons-logging-1.2.jar
- spring-aop-5.3.13.jar
- spring-aspects-5.3.13.jar
- spring-beans-5.3.13.jar
- spring-context-5.3.13.jar
- spring-core-5.3.13.jar
- spring-expression-5.3.13.jar
- aspectjweaver-1.9.7.jar
2. 在 net.biancheng.c.dao 包下,创建一个名为 OrderDao 的接口,代码如下。
3. 在 net.biancheng.c.dao.impl 包下,创建 OrderDao 的实现类 OrderDaoImpl,代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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 的类,代码如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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,配置内容如下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
<?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>
|