Spring 配置使用 - AOP 通知参数
来源:互联网 发布:乐视max2 root软件 编辑:程序博客网 时间:2024/06/06 08:30
基本概念
若想要在通知方法获取被通知方法的参数共有两种方式:自动获取、手动指定。下面来探究下这两种方式的不同之处。
自动获取参数
在介绍 AOP 的通知类型时有提到过环绕通知,该通知类型可以通过参数 ProceedingJoinPoint 自动获取被通知方法的参数值并调用该方法。除了 ProceedingJoinPoint 外,还有 JoinPoint,JoinPoint.StaticPart 也都能自动获取被通知方法的参数。
1.JoinPoint
JoinPoint 即连接点,通过该参数可以获取连接点(被通知方法)的相关信息。
首先来看该接口的继承关系,如下图。可以发现在环绕通知中所使用的 ProceedingJoinPoint 就是继承自该接口。
再来看看该接口的定义:
public interface JoinPoint { // 连接点的具体信息 String toString(); // 连接点的简单信息 String toShortString(); // 连接点的所有信息 String toLongString(); // AOP 代理对象 Object getThis(); // 目标对象 Object getTarget(); // 被通知方法的参数列表 Object[] getArgs(); // 连接点签名 Signature getSignature(); // 连接点方法所在类文件中的位置 SourceLocation getSourceLocation(); // 连接点类型 String getKind(); // 内部接口,暂不探究(下面会提到) public interface StaticPart { //... 省略部分代码 } public interface EnclosingStaticPart extends StaticPart {} // 返回连接点静态部分 StaticPart getStaticPart(); // getKind 方法的返回值 static String METHOD_EXECUTION = "method-execution"; static String METHOD_CALL = "method-call"; static String CONSTRUCTOR_EXECUTION = "constructor-execution"; static String CONSTRUCTOR_CALL = "constructor-call"; static String FIELD_GET = "field-get"; static String FIELD_SET = "field-set"; static String STATICINITIALIZATION = "staticinitialization"; static String PREINITIALIZATION = "preinitialization"; static String INITIALIZATION = "initialization"; static String EXCEPTION_HANDLER = "exception-handler"; static String SYNCHRONIZATION_LOCK = "lock"; static String SYNCHRONIZATION_UNLOCK = "unlock"; static String ADVICE_EXECUTION = "adviceexecution"; }
下面通过简单的例子来探究该接口的作用:
- 定义一个 Bean,用它来表示连接点(joinpoint)的一部分
public class Animals { public void setName(String name) { System.out.println(name); }}
- 定义一个 Bean,用来表示切面
public class AnimalsAspect { public void beforeAdvice() { System.out.println(point.toString()); System.out.println(point.toShortString()); System.out.println(point.toLongString()); System.out.println(point.getThis().toString()); System.out.println(point.getTarget().toString()); System.out.println(point.getArgs()[0]); System.out.println(point.getSignature()); System.out.println(point.getSourceLocation()); System.out.println(point.getKind()); System.out.println(point.getStaticPart()); System.out.println("before advice..." ); }}
- 在 xml 文件中配置
<!-- 1.容器中注入 Bean --><bean id="joinpoint" class="com.demo.Animals" /><bean id="aspect" class="com.aop.AnimalsAspect"/><!-- 2.AOP 配置 --><aop:config> <aop:aspect ref="aspect"> <aop:before method="beforeAdvice" pointcut="execution(* com.demo.Animals.setName(..))" /> </aop:aspect></aop:config>
- 调用验证
String location = ...ApplicationContext factory = new FileSystemXmlApplicationContext(location);Animals animals = (Animals) factory.getBean("joinpoint");animals1.setName("cat");// 输出结果:// execution(void com.demo.Animals.setName(String))// execution(Animals.setName(..))// execution(public void com.demo.Animals.setName(java.lang.String))// com.demo.Animals@4245c97b// com.demo.Animals@4245c97b// cat// void com.demo.Animals.setName(String)// org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@58e22f2b// method-execution// execution(void com.demo.Animals.setName(String))// before advice...// cat
2.ProceedingJoinPoint
该连接点接口只能用于环绕通知,并且该接口继承自 JoinPoint 接口。
public interface ProceedingJoinPoint extends JoinPoint { void set$AroundClosure(AroundClosure arc); // 调用无参的被通知方法 public Object proceed() throws Throwable; // 调用带参的通知方法 public Object proceed(Object[] args) throws Throwable;}
3.JoinPoint.StaticPart
刚连接点是 Joinpoint 的内部接口,作用功能与 JoinPoint 基本一致。
public interface StaticPart { Signature getSignature(); String getKind(); // 连接点标识 int getId(); String toString(); String toShortString(); String toLongString(); }
手动指定参数
手动指定参数,即在配置切面时,需在切面的通知与切面的切点中明确指定参数。
下面通过一个实例来阐明:
- 定义一个 Bean,用它来表示连接点(joinpoint)的一部分
public void Animals { // 该被通知方法存在两个方法参数 public void setName(String param1 , String param2) { System.out.println(param1 +"-"+ param2); }}
- 定义一个 Bean,用来表示切面
public class AnimalsAspect { // 关键 -> 在通知中需明确指定参数名称 public void beforeAdvice(Object param1, Object param2) { System.out.println(param1.toString() + "-" + param2.toString()); }}
- 在 xml 文件中配置
<!-- 1.容器中注入 Bean --><bean id="joinpoint" class="com.demo.Animals" /><bean id="aspect" class="com.aop.AnimalsAspect"/><!-- 2.AOP 配置 --><aop:config> <aop:aspect ref="aspect"> <!-- 关键 -> 在切点中也需明确指定参数名称 --> <aop:before method="beforeAdvice" pointcut="execution(* com.demo.Animals.setName(..)) and args(param1,param2)" /> </aop:aspect></aop:config>
- 调用验证
String location = ...ApplicationContext factory = new FileSystemXmlApplicationContext(location);Animals animals = (Animals) factory.getBean("joinpoint");animals1.setName("cat","dog");// 输出结果:// cat-dog// before advice...// cat-dog
混合使用
当同时采用自动获取参数与手动指定参数时,自动获取参数必须是第一个参数,即 JoinPoint 、ProceedingJoinPoint 等参数并需是通知方法定义的第一个参数。
- 切面通知定义如下:
public void Animals { // JoinPoint 必须是方法定义的第一个参数 public void setName(JoinPoint point , String param1,String param2) { System.out.println(param1 +"-"+ param2); }}
- 在 xml 的配置同上。
0 0
- Spring 配置使用 - AOP 通知参数
- Spring AOP配置及通知参数
- Spring 配置使用 - AOP 通知类型
- Spring aop 通知的使用
- spring AOP 通知参数的传递
- spring aop五种通知及通知中传递参数!
- 基于xml配置的spring aop 的实现日志 和为通知传递参数
- Spring Xml文件配置实现AOP通知
- Spring -- 基于XML的AOP通知配置
- Spring AOP 处理通知中的参数【Spring 入门】
- 【Spring实战】—— 10 AOP针对参数的通知
- Spring AOP-通知-前置通知
- Spring AOP-通知-后置通知
- Spring-AOP-通知-环绕通知
- Spring-AOP-通知-异常通知
- Spring-AOP通知
- spring AOP和通知
- Spring AOP-前置通知
- 正则表达式详细解析
- 【PAT甲级】1024. Palindromic Number (25)
- FROM_UNIXTIME 格式化MYSQL时间戳函数
- 计算连板价
- Android 源码系列之<十一>从源码的角度深入理解AccessibilityService,打造自己的APP小外挂(下)
- Spring 配置使用 - AOP 通知参数
- 自定义View之案列篇(一):魔方
- mysql在dos窗口下的原生使用
- 禁用右键
- Mysql利用Navicat导入导出表
- 台大林轩田机器学习课程笔记4----训练 VS. 测试
- Android线程池
- 华为路由器添加端口映射(带范围NAT)
- 文档