Spring AOP 前切入点及多参数问题
来源:互联网 发布:java点菜系统项目案例 编辑:程序博客网 时间:2024/06/06 13:06
转 http://tonylian.iteye.com/blog/1730433
问题:看了很多关于Spring AOP的文章,在讲各种切入方式(before、around、after-returnning、thrown等)时,被切入的业务主体Bean的方法,基本都是无参数的。
也有提到有参数的,但都是一个String型的参数。以before为例,无参数方法的切点配置为
<aop:before method="before" pointcut="execution(* cn.xxxx..*.*(..))"/>如果方法有一个String型的参数param,则配置为
<aop:before method="before" arg-names="param" pointcut="execution(* cn.xxxx..*.*(..)) and args(param)"/>注:如果参数其实可为任何类型,即Object。如果非要强调是String型,参数为其他类型的方法,不想被切点切入,则可写成 method="before(java.lang.String)"
(经实际测试 arg-names="param" 不写也可以)
但如果 cn.xxxx..*.* 的方法有多个参数,且个数不定,要想让切点可以切入,这么个写法就不行了。
我搜了N多的帖子,也没能找到方法,最终几经辗转,终于在网友的帮助下,点破了这一层窗户纸,其实也很简单,还是在配置的写法:
<aop:before method="before" pointcut="execution(* cn.xxxx..*.*(..)) and args(..)"/>与之配合的切点的写法是
public void before(JoinPoint jp) throws Throwable {...}这样,不论业务Bean的方法有多少个参数,都可以被这个切点切入了。如果需要访问各个参数,只需
Object[] args = jp.getArgs();----------------------------------华丽的分割线-----------------------------------
其实,能够满足如上需求的方法,至少还有一种,就是拦截器。
<bean id="myService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interceptorNames"> <list> <value>beforeInterceptor</value> </list> </property> <property name="target"> <ref bean="realServiceTarget" /> </property> </bean> <bean id="realServiceTarget" class="cn.xxxx.xxx.Xxxx"/> <bean id="beforeInterceptor" class="cn.xxxx.xxx.MyChecker"/>思路是在注入ServiceBean时,偷梁换柱一下,用myService代替,实际是指向Spring的拦截器,它可以在执行真正的ServiceBean之前,先执行beforeInterceptor所指向的拦截代码
(这里是MyChecker,这个拦截器要实现org.aopalliance.intercept.MethodInterceptor接口,并完成public Object invoke(MethodInvocation invocation) throws Throwable方法)然后再交还给target属性指明的真正的ServiceBean。它不仅仅能够得到方法的参数,而且还有更强的功能——决定是否继续执行target。
public class MyChecker implements MethodInterceptor {/** * 用户访问认证方法。 * 如果登录合法则开始执行服务,否则返回错误。 */public Object invoke(MethodInvocation invocation) throws Throwable {Method invokeMethod = invocation.getMethod();Object[] args = invocation.getArguments();... if(....){ return invocation.proceed(); // 检查OK,继续执行 }else{ return null; // 检查NG,阻断执行 } }}
看到了吧,这里不仅仅可以得到目标方法的参数 Object[] args = invocation.getArguments();
还可以,控制是否要继续执行目标方法,还是阻断。因此用来做认证是再合适不过了。
----------------------------------华丽的分割线-----------------------------------
为什么要加入两条分割线之间的之一段呢?除了也作为before切入的另一种实现方式,更主要的是想引出下面的问题:
我发现,在我成功的用AOP切入之后,每次都执行了两遍切点,且我检查了配置文件,并没有重复定义<AOP>
当我在切点代码中加入
Object target = jp.getTarget();
我发现,这个target有一次是我的ServiceBean,而另一次是类似$Proxy22之类的东西。这才恍然大悟,它应该是那个拦截器!也就是说,拦截器被切点切入了一次,真正的target又切入了一次。
显然,从配置文件的写法上似乎是无法避免拦截器被切入的(虽然org.springframework.aop.framework.* 并不是切面),那只能在切点里想办法回避了
public void before(JoinPoint jp) throws Throwable { Object target = jp.getTarget(); if(AopUtils.isAopProxy(target)){ return; } ... }
至此,可以让多参数方法被切入的before切点完成了。
(after-returnning没有遇到什么障碍,多参数也很简单,甚至不用在pointcut配置中声明,还可取到返回值)
切点,可以同时得到JoinPoint和返回值
<aop:after-returning method="afterReturning" arg-names="retVal" returning="retVal" pointcut="execution(* cn.xxxx..*.*(..))"/>
0 0
- Spring AOP 前切入点及多参数问题
- Spring AOP 前切入点及多参数问题
- Spring AOP概念及切入点
- Spring AOP 定义切入点
- spring aop 切入点
- Spring AOP 定义切入点
- Spring AOP切入点表达式
- Spring AOP 切入点表达式
- Spring的AOP(三):切入点Pointcut 、Advisor及引入
- Spring-AOP配置切入点方式及配置各种类型增强
- Spring-AOP配置切入点方式及配置各种类型增强
- Spring AOP execution 切入点表达式
- spring aop 复习 .2 切入点
- Spring AOP execution 切入点表达式
- Spring Aop 切入点表达式解析
- Spring AOP 切入点表达式使用
- Spring AOP 切入点常用表达式
- spring AOP切入点表达式规则
- AFNetworking2.0源码解析<一>
- 提高linux并发处理能力
- 通俗易懂的介绍匈牙利算法
- Java实现定时任务的三种方法
- 轮廓提取
- Spring AOP 前切入点及多参数问题
- linux下的并发处理
- ubuntu gdb 多线程调试步骤
- 自己动手搭建免费VoIP服务器
- 源码安装yum
- android 网络判断工具类(APN+WIFI)
- 仿QQ布局实例
- 销售部年终总结酒店服务员年终总结
- njupt-1134-Christmas