`
jinnianshilongnian
  • 浏览: 21432036 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2404633
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997324
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631174
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257473
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593044
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248922
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847149
Group-logo
跟我学Nginx+Lua开...
浏览量:697994
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780320
社区版块
存档分类
最新评论

【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3

阅读更多

       前边章节已经介绍了声明通知,但如果想获取被被通知方法参数并传递给通知方法,该如何实现呢?接下来我们将介绍两种获取通知参数的方式。

  • 使用JoinPoint获取:Spring AOP提供使用org.aspectj.lang.JoinPoint类型获取连接点数据,任何通知方法的第一个参数都可以是JoinPoint(环绕通知是ProceedingJoinPoint,JoinPoint子类),当然第一个参数位置也可以是JoinPoint.StaticPart类型,这个只返回连接点的静态部分。

1) JoinPoint提供访问当前被通知方法的目标对象、代理对象、方法参数等数据:

 

java代码:
package org.aspectj.lang;
import org.aspectj.lang.reflect.SourceLocation;
public interface JoinPoint {
    String toString();         //连接点所在位置的相关信息
    String toShortString();     //连接点所在位置的简短相关信息
    String toLongString();     //连接点所在位置的全部相关信息
    Object getThis();         //返回AOP代理对象
    Object getTarget();       //返回目标对象
    Object[] getArgs();       //返回被通知方法参数列表
    Signature getSignature();  //返回当前连接点签名
    SourceLocation getSourceLocation();//返回连接点方法所在类文件中的位置
    String getKind();        //连接点类型
    StaticPart getStaticPart(); //返回连接点静态部分
}

 

2ProceedingJoinPoint:用于环绕通知,使用proceed()方法来执行目标方法:

java代码:
public interface ProceedingJoinPoint extends JoinPoint {
    public Object proceed() throws Throwable;
    public Object proceed(Object[] args) throws Throwable;
}

 

3) JoinPoint.StaticPart提供访问连接点的静态部分,如被通知方法签名、连接点类型等:

 

java代码:
public interface StaticPart {
    Signature getSignature();    //返回当前连接点签名
    String getKind();          //连接点类型
    int getId();               //唯一标识
    String toString();         //连接点所在位置的相关信息
    String toShortString();     //连接点所在位置的简短相关信息
    String toLongString();     //连接点所在位置的全部相关信息
}

 

使用如下方式在通知方法上声明,必须是在第一个参数,然后使用jp.getArgs()就能获取到被通知方法参数:

 

java代码:
@Before(value="execution(* sayBefore(*))")
public void before(JoinPoint jp) {}
 
@Before(value="execution(* sayBefore(*))")
public void before(JoinPoint.StaticPart jp) {}

 

  • 自动获取:通过切入点表达式可以将相应的参数自动传递给通知方法,例如前边章节讲过的返回值和异常是如何传递给通知方法的。

在Spring AOP中,除了execution和bean指示符不能传递参数给通知方法,其他指示符都可以将匹配的相应参数或对象自动传递给通知方法。

 

java代码:
@Before(value="execution(* test(*)) && args(param)", argNames="param")
public void before1(String param) {
    System.out.println("===param:" + param);
}

 

       切入点表达式execution(* test(*)) && args(param) :

1)首先execution(* test(*))匹配任何方法名为test,且有一个任何类型的参数;

2)args(param)将首先查找通知方法上同名的参数,并在方法执行时(运行时)匹配传入的参数是使用该同名参数类型,即java.lang.String;如果匹配将把该被通知参数传递给通知方法上同名参数。

其他指示符(除了execution和bean指示符)都可以使用这种方式进行参数绑定。

在此有一个问题,即前边提到的类似于【3.1.2构造器注入】中的参数名注入限制:class文件中没生成变量调试信息是获取不到方法参数名字的。

所以我们可以使用策略来确定参数名:

 

 

 

1、如果我们通过“argNames”属性指定了参数名,那么就是要我们指定的;

java代码:
@Before(value=" args(param)", argNames="param") //明确指定了
public void before1(String param) {
    System.out.println("===param:" + param);
}

 

2、如果第一个参数类型是JoinPoint、ProceedingJoinPoint或JoinPoint.StaticPart类型,应该从“argNames”属性省略掉该参数名(可选,写上也对),这些类型对象会自动传入的,但必须作为第一个参数;

java代码:
@Before(value=" args(param)", argNames="param") //明确指定了
public void before1(JoinPoint jp, String param) {
    System.out.println("===param:" + param);
}

 

 3、如果“class文件中含有变量调试信息”将使用这些方法签名中的参数名来确定参数名;

 

java代码:
@Before(value=" args(param)") //不需要argNames了
public void before1(JoinPoint jp, String param) {
    System.out.println("===param:" + param);
}

 

 4、如果没有“class文件中含有变量调试信息”,将尝试自己的参数匹配算法,如果发现参数绑定有二义性将抛出AmbiguousBindingException异常;对于只有一个绑定变量的切入点表达式,而通知方法只接受一个参数,说明绑定参数是明确的,从而能配对成功。

 

java代码:
@Before(value=" args(param)")
public void before1(JoinPoint jp, String param) {
    System.out.println("===param:" + param);
}

5、以上策略失败将抛出IllegalArgumentException。

 

接下来让我们示例一下组合情况吧:

 

java代码:
@Before(args(param) && target(bean) && @annotation(secure)",
        argNames="jp,param,bean,secure")
public void before5(JoinPoint jp, String param,
 IPointcutService pointcutService, Secure secure) {
……
}

 

           该示例的执行步骤如图6-5所示。

 

图6-5 参数自动获取流程

 

 

除了上边介绍的普通方式,也可以对使用命名切入点自动获取参数: 

 

java代码:
	
@Pointcut(value="args(param)", argNames="param")
private void pointcut1(String param){}
@Pointcut(value="@annotation(secure)", argNames="secure")
private void pointcut2(Secure secure){}
   
@Before(value = "pointcut1(param) && pointcut2(secure)",
 argNames="param, secure")
public void before6(JoinPoint jp, String param, Secure secure) {
……
}

 

       自此给通知传递参数已经介绍完了,示例代码在cn.javass.spring.chapter6.ParameterTest文件中。

 

 

原创内容,转载请注明出处【http://sishuok.com/forum/blogPost/list/0/2473.html

 

21
0
分享到:
评论
6 楼 dagger9527 2019-08-16  
holyselina 写道
您前面说到能获取调用是的参数数组,我想问下,我想在通知方法中,获取当前调用代理对象的方法名称,有办法么?谢谢

String js = jp.getSignature().toString();
System.out.println(js.substring(js.lastIndexOf(".") + 1).replaceAll("\\(.*?\\)", ""));
5 楼 holyselina 2013-03-24  
jinnianshilongnian 写道
holyselina 写道
您前面说到能获取调用是的参数数组,我想问下,我想在通知方法中,获取当前调用代理对象的方法名称,有办法么?谢谢

JoinPoint

我已经知道了谢谢,有个获取签名方法getSignature中包含相关信息
4 楼 jinnianshilongnian 2013-03-19  
holyselina 写道
您前面说到能获取调用是的参数数组,我想问下,我想在通知方法中,获取当前调用代理对象的方法名称,有办法么?谢谢

JoinPoint
3 楼 holyselina 2013-03-19  
您前面说到能获取调用是的参数数组,我想问下,我想在通知方法中,获取当前调用代理对象的方法名称,有办法么?谢谢
2 楼 jinnianshilongnian 2012-07-23  
sky小紫 写道
[img][/img]
[url][/url]
引用


?
1 楼 sky小紫 2012-07-23  
[img][/img]
[url][/url]
引用

相关推荐

    跟我学spring3(1-7)

    【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3 【第六章】 AOP 之 6.7 通知顺序 ——跟我学spring3 【第六章】 AOP 之 6.8 切面实例化模型 ——跟我学spring3 【第六章】 AOP 之 6.9 代理机制 ——跟我学...

    跟开涛学Spring

    1.25 【第六章】 AOP 之 6.6 通知参数 ——跟我学spring3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .274 1.26 【第六章】 AOP 之 6.7 通知顺序 ——跟我学spring3 . . . . . . . . . . ...

    跟我学spring3(1-7).pdf

    Spring概述2.1 IoC基础2.2 IoC 容器基本原理2.3 IoC的配置使用——跟我学Spring33.1 DI的配置使用3.2 循环依赖3.3 更多DI的知识 3.4 Bean的作用域 4.1 基础知识4.2 内置Resource实现4.3 访问Resource4.4 Resource...

    Xabber客户端.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    XUI-master.zip

    一个简洁而又优雅的Android原生UI框架,解放你的双手!还不赶紧点击使用说明文档,体验一下吧! 涵盖绝大部分的UI组件:TextView、Button、EditText、ImageView、Spinner、Picker、Dialog、PopupWindow、ProgressBar、LoadingView、StateLayout、FlowLayout、Switch、Actionbar、TabBar、Banner、GuideView、BadgeView、MarqueeView、WebView、SearchView等一系列的组件和丰富多彩的样式主题。

    基于背向散射的超声骨密度仪算法研究和软件设计的任务书.docx

    基于背向散射的超声骨密度仪算法研究和软件设计的任务书.docx

    机械毕业设计81五自由度机械臂设计.doc

    机械毕业设计81五自由度机械臂设计.doc

    数据可视化-上海各地区风速热力图

    数据可视化-上海各地区风速热力图

    侧边栏滑动.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    RBF神经网络概述.doc

    RBF神经网络概述.doc

    游戏植物大战僵尸(经典版)

    游戏植物大战僵尸(经典版)

    社会工程优化器 (SEO) 元启发式优化算法matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    基于s7200自动售货机-plc-控制.doc

    基于s7200自动售货机-plc-控制.doc

    基于深度学习方法去评估锂电池健康状态(SOH)python源码.zip

    基于深度学习方法去评估锂电池健康状态(SOH)python源码.zip对象是NASA的锂电池容量衰退数据集,本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于深度学习方法去评估锂电池健康状态(SOH)python源码.zip对象是NASA的锂电池容量衰退数据集,本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。基于深度学习方法去评估锂电池健康状态(SOH)python源码.zip对象是NASA的锂电池容量衰退数据集,本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 基于深度学习方法去评估锂电池健康状态(SOH)python源码.zip对象是NASA的锂电池容量衰退数据集,本资源中的源码都是经过本地编译过可运行的,评审分

    电脑工具.txt

    电脑工具.txt

    梯度金字塔机制(GPM)元启发式优化算法matlab代码.zip

    1.版本:matlab2014/2019a/2021a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。

    安卓图片旋转放大缩写透明度调整例子.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    移动机器人机械臂的设计小论文.doc

    移动机器人机械臂的设计小论文.doc

    thermometer_仪表盘.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

    带暂停功能倒计时TimeCountDown盒子适用.zip

    android 源码学习. 资料部分来源于合法的互联网渠道收集和整理,供大家学习参考与交流。本人不对所涉及的版权问题或内容负法律责任。如有侵权,请通知本人删除。感谢CSDN官方提供大家交流的平台

Global site tag (gtag.js) - Google Analytics