Spring-AOP学习
Posted defender
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring-AOP学习相关的知识,希望对你有一定的参考价值。
1.AOP中的术语
【1】连接点(JoinPoint): UserDaoImpl实现类中所有的方法称为连接点(JoinPoint)
save()方法
update()方法
【2】切入点pointcut:拦截哪些个方法(对哪个方法做增强,save(),update())
【3】通知/增强advice:具体做什么功能。如记录日志
五种通知类型。
【4】目标对象target:UserDaoImpl称为目标对象
【5】织入waving:过程,把通知/增强添加到目标对象,生成代理对象的过程
【6】代理proxy:生成代理对象
【7】切面aspect:切入点 + 通知的组合称为切面
通知---->自定义编写
切入点--->自定义配置
2.测试
需求:在save方法执行之前,不改变原码输入日志记录
相应的接口和实现类
1 //接口
2 public interface UserDao{
3 public void save();
4 public void update();
5 }
1 //实现类
2 public class UserDao implements UserDao{
3 public void save(){
4 System.out.println("保存用户...");
5 }
6 public void update(){
7 System.out.println("修改用户...");
8 }
9 }
切面类
1 /**
2 * 【步骤1】定义切面类:切入点Pointcut + 通知Advice
3 */
4 public class MyAspectXml {
5 /*
6 * 【步骤1】定义切面类:切入点Pointcut + 通知Advice
7 *
8 * 【步骤2】通知(具体的增强方法)
9 * 通知类型
10 *
11 * 【步骤3】配置applicationContext.xml文件
12 *
13 * 【步骤4】<!-- 编写切面类配置 --> <bean id="myAspectXml" class="com.hl.aspects.MyAspectXml" />
14 *
15 * 【步骤5】<!-- 配置AOP -->
16 * <aop:config>
17 * 【步骤6】<!-- 配置切面类:切入点 + 通知 (类型)-->
18 * <aop:aspect ref="myAspectXml">
19 * 【步骤7】<!-- 配置的前置通知,save方法执行之前,增强的方法会执行 -->
20 * <!--切入点的表达式:execution(public void com.hl.impl.CustomerDaoImpl.save()) -->
21 * <aop:before method="log" pointcut="execution(public void com.hl.impl.CustomerDaoImpl.save())"/>
22 * </aop:aspect>
23 * </aop:config>
24 */
25
26 //通知(具体的增强)
27 public void log(){
28 System.out.println("记录日志...");
29 }
30
31 /*
32 * 最终通知:方法执行成功或出现异常,都会执行
33 */
34 public void after(){
35 System.out.println("最终通知...");
36 }
37
38 /*
39 * 后置通知:执行后通知,程序出现了异常后,后置通知不会执行的
40 *
41 */
42 public void afterReturn(){
43 System.out.println("后置通知...");
44 }
45
46 /*
47 * 环绕通知:方法执行之前和方法执行之后进行通知,默认情况下,目标对象的方法是不能执行的。需手动让目标对象的方法执行。
48 *
49 */
50 public void around(ProceedingJoinPoint joinPoint){
51 System.out.println("环绕通知1...");
52
53 //手动让目标对象的方法去执行,常用于事务管理
54 try {
55 joinPoint.proceed();
56 } catch (Throwable e) {
57 e.printStackTrace();
58 }
59
60 System.out.println("环绕通知2...");
61 }
66 }
配置文件applicationContext.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"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:aop="http://www.springframework.org/schema/aop"
6 xmlns:tx="http://www.springframework.org/schema/tx"
7 xsi:schemaLocation="http://www.springframework.org/schema/beans
8 http://www.springframework.org/schema/beans/spring-beans.xsd
9 http://www.springframework.org/schema/context
10 http://www.springframework.org/schema/context/spring-context.xsd
11 http://www.springframework.org/schema/aop
12 http://www.springframework.org/schema/aop/spring-aop.xsd
13 http://www.springframework.org/schema/tx
14 http://www.springframework.org/schema/tx/spring-tx.xsd">
15
16 <!-- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
17 xmlns:aop="http://www.springframework.org/schema/aop"
18 xmlns:context="http://www.springframework.org/schema/context"
19 xsi:schemaLocation="http://www.springframework.org/schema/beans
20 http://www.springframework.org/schema/beans/spring-beans.xsd
21 http://www.springframework.org/schema/aop
22 http://www.springframework.org/schema/aop/spring-aop.xsd
23 http://www.springframework.org/schema/context
24 http://www.springframework.org/schema/context/spring-context.xsd"> -->
25 <!-- bean definitions here -->
26 <!-- 配置客户的dao -->
27 <bean id="customerDao" class="com.hl.service.impl.CustomerDaoImpl"></bean>
28
29 <!-- 【步骤4】编写切面类配置 -->
30 <bean id="myAspectXml" class="com.hl.aspects.MyAspectXml" />
31
32 <!-- 配置AOP -->
33 <aop:config>
34 <!-- 配置切面类:切入点 + 通知 (类型)-->
35 <aop:aspect ref="myAspectXml">
36
37 <!-- 配置的前置通知,save方法执行之前,增强的方法会执行 -->
38 <!-- 1. 前置通知 -->
39 <aop:before method="log" pointcut="execution(public void com.hl.service.impl.CustomerDaoImpl.save(..))"/>
40
41 <!-- 2. 最终通知 -->
42 <!-- <aop:after method="after" pointcut-ref="execution(public void com.hl.impl.CustomerDaoImpl.save(..))"/> -->
43
44 <!-- 3. 后置通知 -->
45 <!-- <aop:after-returning method="afterReturnning" pointcut-ref="execution(public void com.hl.impl.CustomerDaoImpl.save(..))"/> -->
46
47 <!-- 4. 异常抛出通知 -->
48
49 <!-- 5. 环绕通知 -->
50 <!-- <aop:around method="around" pointcut-ref="execution(public void com.hl.impl.CustomerDaoImpl.save(..))"/> -->
51
52 <!-- 切入点的表达式:execution(public void com.hl.impl.CustomerDaoImpl.save()) -->
53 <!-- 切入点的表达式
54 1.execution() 固定的,不能省略
55
56 2.public 可省略不写
57 <aop:before method="log" pointcut="execution(void com.hl.impl.CustomerDaoImpl.save(..))"/>
58
59 3.void 返回值类型可以出现*号,表示任意的返回值,返回值类型不能不写
60 <aop:before method="log" pointcut="execution(* com.hl.impl.CustomerDaoImpl.save(..))"/>
61
62 4.包名可使用*代替,不能省略,简写方式:*..*方法
63 <aop:before method="log" pointcut="execution(* com.hl.*.CustomerDaoImpl.save(..))"/>
64
65 包的简写方式,任意的包的结构
66 <aop:before method="log" pointcut="execution(* *..*.CustomerDaoImpl.save(..))"/>
67
68 5.*DaoImpl,包名以DaoImpl结尾的
69 编写类的写法
70 <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save(..))"/>
71
72 6.方法save*
73 方法的编写
74 <aop:before method="log" pointcut="execution(* *..*.*DaoImpl.save*())"/>
75
76 7.方法的参数:..表示任意的参数
77 参数列表:出现一个*,表示一个参数;任意参数使用..
78 <aop:before method="log" pointcut="execution(void com.hl.impl.CustomerDaoImpl.save*())"/>
79 <aop:before method="log" pointcut="execution(void com.hl.impl.CustomerDaoImpl.save*(..))"/>
80 -->
81
82 </aop:aspect>
83 </aop:config>
84 </beans>
3.小结
实现类中重写接口方法,UserDaoImpl实现类中所有的方法即连接点。
在不改变原码而增加需求时,可定义与实现类平级的切面类,即目标类的切入点(目标类中的所有方法)和增强/通知(新增功能)来定义切面类。
关于xml配置文件,则是常规的配置方式:
配置切面类bean
配置AOP----配置(类切入点和通知)-----配置通知类型
以上是关于Spring-AOP学习的主要内容,如果未能解决你的问题,请参考以下文章