`
flyPig
  • 浏览: 137038 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

SpringAOP的一个问题

阅读更多
问题:项目中用到了AOP方式记录日志,对于所有create开头的方法全部做了拦截。现在有一个类,里面有createFile方法和newFolder方法,newFolder方法里面会调用到createFile方法,但此时,createFile的拦截记录日志却起不到作用,这是为什么呢。

缘由:Spring的AOP实现方式有两种:Java动态代理和Cglib动态增强,这两种方式在Spring中是可以无缝自由切换的。Cglib方式增强的AOP目标类,会创建两个对象,一个是Bean实例本身,一个是Cglib增强代理对象。Spring通过AopProxy接口,抽象了这两种实现,实现了一致的AOP方式。但是这种抽象带了一个缺陷,那就是扼杀了Cglib能够直接创建普通类的增强子类的能力,Spring相当于把Cglib动态生成的子类,当普通的代理类了。回到问题上就是:newFolder方法经过AopProxy给过滤掉,方法内部调用createFile,虽然配置了方法拦截,但是因为是内部调用,AopProxy感知不到,因此拦截日志起不到作用。

延伸:这个问题,可以延伸到同样AOP性质的声明式事务。如果createFile配置了事务,但是newFolder没有配置,同理,newFolder方法内的createFile并不会开启事务,假设createFile被调用了3次,第三次产生错误,事务并不能正常的回滚了。因此可以认为:内部调用时,被调用方法的事务声明将不起作用;同样事务的传播策略在内部方法调用时将不起作用

解决:这个东西我没想到什么好方法改变,只能避开Spring目前的AOP实现上的限制,要么都声明要事务,要么分开成两个类,要么直接在方法里使用编程式事务。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics