spring AOP--AspectJ---xml
本文详细介绍了如何使用AspectJ与Spring框架集成实现面向切面编程(AOP),包括配置切面、切入点、通知等关键概念及XML配置方法,通过实例展示了AspectJ的强大功能。
文章信息
- 原文链接:https://jiayq.blog.csdn.net/article/details/87816295
- 发布时间:2019-02-20 19:21:30
- 阅读量:771
- 分类:java同时被 3 个专栏收录, 订阅专栏, spring
- 标签:#springAOP AspectJ, #基于xm声明的AspectJ, #spring切入点表达式, #AspectJ通知类型, #如何配置一个AspectJ的SpringAOP
摘要
文章浏览阅读771次。本文详细介绍了如何使用AspectJ与Spring框架集成实现面向切面编程(AOP),包括配置切面、切入点、通知等关键概念及XML配置方法,通过实例展示了AspectJ的强大功能。
基于xml的AspectJ
- 1.AspectJ介绍
- 2.aop:config
- 3.如何配置
- 3.1配置切面
- 3.2配置切入点
- 3.3配置通知
- 3.1配置切面
- 4.例子
- 4.1准备
- 4.2创建一个spring工程
- 4.3创建Java文件
- 4.4xml文件
- 4.5运行结果
- 4.1准备
- 5.总结
1.AspectJ介绍
AspectJ是一个基于Java语言的AOP框架,他提供了强大的AOP功能。Spring2.0以后,SpringAOP引入了对AspectJ的支持。
使用AspectJ实现AOP有两种方式:
1.基于xml的声明式AspectJ;
2.基于注解的声明式AspectJ;
2.aop:config

spring配置文件中的元素下可以包含多个aop:config元素,一个aop:config元素中又可以包含属性和子元素。
其层级关系如上图所示。
3.如何配置
3.1配置切面
aop:aspect元素
id用于定义该切面的唯一标识;
ref用于引用普通的SpringBean;
3.2配置切入点
aop:pointcut元素
当aop:pointcut是aop:config的直接子元素时,表示全局的切入点。
如果aop:pointcut是aop:aspect的直接子元素时,表示局部切入点。
id用于指定切入点的唯一标识;
expression用于指定切入点关联的切入点表达式。
切入点表达式:
1
execution(* com.bean.*.*(..))
其中execution()是表达式的主体
第一个*表示方法的返回类型
1
com.bean.*.*
第一个 _表示XXX类
第二个_表示的是XXX方法
1
(..)
两个点表示的是任意参数
springAOP中切入点表达式的基本格式如下:
1
execution(modifiers-pattern?ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern)
modifiers-pattern:表示定义的目标方法的访问修饰符:public,private…
ret-type-pattern:表示定义的目标方法的返回值类型:void,String…
declaring-type-pattern:表示定义的目标方法的类路径:com.bean。。。。
name-pattern:表示具体需要被代理的目标方法:add()。。。
param-pattern:表示需要被代理的目标方法包含的参数;
throws-pattern:表示需要被代理的目标方法抛出的异常类型。
其他带有?的标识都是选填项。
3.3配置通知
pointcut:该属性用于指定一个切入点表达式
pointcut-ref该属性指定一个已经存在的植入点名称
pointcut与pointcut-ref二选一
method该属性指定一个方法名,指定将切面bean中的该方法转换为增强处理
throwing该属性支队after-throwing元素有效,用于指定一个形参名,异常通知方法可以通过改形参访问目标方法所抛出的异常
returning该属性支队after-returning元素有效,用于指定衣蛾形参名,后置通知方法可以通过该形参访问目标增强方法的返回值。
4.例子
4.1准备
aspectjrt-1.8.10.jar
aspectjweaver-1.8.10.jar
4.2创建一个spring工程
4.3创建Java文件
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
//@Aspect
//@Component("aspect")
public class MyAspect {
public void before(){
System.out.println("前置通知");
System.out.println("MyAspect#before");
}
public void after(JoinPoint joinpoint){
System.out.println("后置通知");
System.out.println("MyAspect#after");
System.out.println(joinpoint.getSignature().getName());
}
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("MyAspect#around#before");
System.out.println("环绕通知#前置通知");
Object object = proceedingJoinPoint.proceed();
System.out.println("环绕通知#后置通知");
System.out.println("MyAspect#around#after");
return object;
}
public void afterThrow(JoinPoint joinPoint,Throwable e){
System.out.println("异常通知");
System.out.println("MyAspect#afterThrow");
System.out.println(e.getMessage());
}
public void afterAfter(){
System.out.println("最终通知");
System.out.println("MyAspect#after#after");
}
}
package bean;
import org.springframework.stereotype.Component;
//@Component("people")
public class People{
/**
*
*/
private static final long serialVersionUID = 6664089908413976436L;
public void say(){
System.out.println("People#say");
// int a = 3/0;
}
}
package client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.People;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"resource/*.xml");
People people = (People) applicationContext.getBean("people");
people.say();
}
}
4.4xml文件
bean.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
<?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"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 目标bean -->
<context:annotation-config/>
<!-- 指定需要扫描的包 -->
<!--
<context:component-scan base-package="bean,aspect"></context:component-scan>
-->
<bean id="people" class="bean.People"></bean>
<!-- 增强类 -->
<bean id="aspect" class="aspect.MyAspect"></bean>
<!-- aop编程 -->
<aop:config>
<!-- 配置切面 -->
<aop:aspect ref="aspect">
<!-- 配置切入点 -->
<aop:pointcut expression="execution(* bean.*.*(..))" id="aspectPoint"/>
<!-- 关联切入点和增强类 -->
<!-- 前置通知 -->
<aop:before method="before" pointcut-ref="aspectPoint"/>
<!-- 后置通知 -->
<aop:after-returning method="after" pointcut-ref="aspectPoint" returning="returnVal"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="aspectPoint"/>
<!-- 异常通知 -->
<aop:after-throwing method="afterThrow" pointcut-ref="aspectPoint" throwing="e"/>
<!-- 最终通知 -->
<aop:after method="afterAfter" pointcut-ref="aspectPoint"/>
</aop:aspect>
</aop:config>
</beans>
4.5运行结果
1
2
3
4
5
6
7
8
9
10
11
12
前置通知
MyAspect#before
MyAspect#around#before
环绕通知#前置通知
People#say
最终通知
MyAspect#after#after
环绕通知#后置通知
MyAspect#around#after
后置通知
MyAspect#after
say
5.总结
AspectJ 是一个基于Java的AOP框架,spring2.0之后
SpringAOP引入对AspectJ的支持,并允许直接进行编程。

