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

【第六章】 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]
引用

相关推荐

    跟开涛学Spring

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

    跟我学spring3pdf,高清

    《跟我学Spring3》是一本深入浅出的Spring框架学习指南,主要针对Spring 3.x版本进行讲解。这本书旨在帮助初学者和有一定经验的开发者更好地理解和应用Spring框架,提升其在实际开发中的技能。PDF文档提供了清晰的...

    跟我学spring3

    《跟我学Spring3》是一本深入浅出的Spring框架学习指南,主要针对Spring 3.x版本进行详细讲解。Spring作为Java领域最流行的轻量级框架,它的应用广泛且功能强大,涵盖依赖注入、AOP(面向切面编程)、数据访问、Web...

    跟我学spring

    标题“跟我学spring”和描述“spring 的使用,每个知识点和项目中的运用,20章的介绍。”暗示这是一份详细介绍Spring框架使用方法的教程或手册,覆盖了Spring的各个方面,并以实例为导向,深入探讨了每个知识点在...

    跟我学spring3(总共13章)8

    《跟我学Spring3》系列教程是为初学者和有经验的开发者提供的一份全面而深入的Spring框架学习资源。Spring3作为Java企业级应用开发的重要框架,它的核心特性包括依赖注入、AOP(面向切面编程)、数据访问、Web开发等...

    跟我学spring3(总共13章)6

    《跟我学Spring3》是针对初学者和有一定基础的开发者设计的一套全面、深入的教程,旨在帮助读者理解和掌握Spring3框架的核心概念和技术。本教程共计13个章节,覆盖了Spring3.0和3.x版本的主要特性。下面将详细阐述第...

    开涛 跟我学spring3 pdf+源码

    这本书分为两部分PDF文档:"开涛 跟我学spring3(1-7).pdf" 和 "开涛 跟我学spring3(8-13).pdf",分别覆盖了Spring框架的核心概念和技术,旨在帮助读者全面理解并掌握Spring框架的应用。 在第一部分(1-7章)中,...

    跟我学Spring3

    《跟我学Spring3》这本书是针对Java开发人员深入学习Spring框架第三版的一份教程。Spring作为Java企业级应用开发中的核心框架,它以其强大的功能、灵活性和模块化设计深受开发者喜爱。Spring3版本在前一版本基础上...

    跟我学spring3(1-13)

    《跟我学Spring3》是一本深入浅出介绍Spring框架的电子书,分为两部分,分别是“跟我学Spring3(8-13).pdf”和“跟我学Spring3(1-7).pdf”,全面覆盖了Spring框架的核心概念和技术。Spring作为Java开发中的主流框架,...

    跟我学spring3 .pdf

    《跟我学Spring3》这本书是针对Spring框架进行深入解析的一本教程,涵盖了Spring的核心特性,包括IoC(Inversion of Control,控制反转)、DI(Dependency Injection,依赖注入)、AOP(Aspect-Oriented Programming...

    跟我学Spring,Spring3学习资料

    - **AOP基础:** 介绍AOP的概念及其在Spring中的应用,主要包括切面、连接点、通知等概念。 - **AOP的HelloWorld:** 一个简单示例,通过实现一个切面来展示AOP的基本使用。 - **基于Schema的AOP和基于@AspectJ的AOP...

    跟我学spring3(1-7)

    《跟我学Spring3》系列教程涵盖了Spring框架的核心概念和技术,包括IoC(Inversion of Control,控制反转)、DI(Dependency Injection,依赖注入)、资源管理、Spring表达式语言(SpEL)以及面向切面编程(AOP)等...

    五、Spring源码分析——Spring Aop

    《Spring AOP 源码分析》 在深入探讨Spring AOP之前,我们先要理解AOP(面向切面编程)的基本概念。AOP是一种编程范式,它将关注点分离,使得我们可以将横切关注点(如日志、事务管理、安全检查等)与业务逻辑解耦...

    跟我学spring3(总共13章)13

    《跟我学Spring3》是针对初学者和有一定基础的开发者设计的一套全面、深入的教程,共计13个章节,涵盖了Spring3的核心概念和技术。Spring3作为Java开发中备受推崇的框架,它提供了丰富的功能,包括依赖注入、AOP...

    Spring 入门案例——AOP

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。本入门案例将帮助你理解并掌握Spring AOP的基本概念和使用方法。 在...

Global site tag (gtag.js) - Google Analytics