Spring的@Transactional为什么不能在受保护的方法上工作?

财富

上一个私有方法春天在什么@Transactional属性的工作?

使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释对受保护的,私有的或程序包可见的方法进行注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。

我可以想到排除privatepackage-private方法的充分理由,但是为什么protected方法不能在事务上表现呢?以下堆栈跟踪显示了公共方法(通过接口代理调用)的正确行为:

at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_51]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at com.sun.proxy.$Proxy145.improveType(Unknown Source) ~[na:na]

当调用“相同的”受保护方法(通过非接口CGLIB代理)时,我们得到以下信息:

at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_51]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:720) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) ~[spring-aop-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at my.company.webservices.facade.EntityFacade$$EnhancerBySpringCGLIB$$fd77735b.findEntity(<generated>) ~[spring-core-4.2.1.RELEASE.jar:na]

这显然是一个设计决定(为什么?),但我认为这很可疑,因为它显然是开发人员错误,但它会在无提示的情况下失败。

编辑使用接口(仅接口中的公共方法)时,这显然不是问题,但是由于Spring不一定需要接口来通过CGLIB代理对象,因此调用受保护的@Transactional方法的行为就像公共方法(即,通过代理),只是设计上忽略了交易性。

久拉·拉卡托斯(Gyula Lakatos)

因为这:

在代理模式(默认)下,将仅拦截通过代理传入的“外部”方法调用。这意味着即使调用的方法标记有@Transactional,“自调用”(即目标对象内的方法调用目标对象的其他方法)也不会在运行时导致实际事务!

和这个:

由于Spring的AOP框架基于代理的性质,从定义上讲,无论是JDK代理(不适用)还是CGLIB代理(在技术上可行,但不建议用于AOP的目的),都不会拦截受保护的方法。结果,任何给定的切入点将仅与公共方法匹配!

Spring的家伙可能希望与JDK代理保持一致。您不希望基于JDK和CGLIB具有不同的代理配置和不同的结果。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么chmod不能在/ media下的文件上工作?

centos devtools repo为什么不能在redhat上工作?

为什么Solr查询不能在空格上工作?

为什么后递增运算符不能在返回int的方法上工作?

C ++:为什么不能在派生类中访问受保护的构造方法?

为什么 API 不能在移动设备上工作而在计算机上工作?

为什么此XMLHttpRequest可以在Firefox Scratchpad中工作,而不能在localhost上工作?

为什么Powershell Env可以在本地工作但不能在dockerfile上工作?

它可以在桌面上正常工作,但不能在android上工作。为什么?

为什么std :: make_move_iterator可以在vector <string>上工作而不能在vector <int>上工作

为什么不能从子类访问受保护的方法?

为什么接口不能具有受保护的方法

不知道为什么这个 stream() 不能在这个嵌套列表上工作?

为什么应用的函数不能在data.table的所有行上工作?

为什么这个 Dijkstra 不能在有向图上工作

为什么这个用于在悬停时反转颜色的 CSS 不能在我的图像上工作?

为什么不选中就不能在字节上工作?

为什么jQuery Datepicker不能在两个输入值上工作?

正则表达式为什么不能在PreviewKeyDown上工作?

为什么我的简单pytorch网络不能在GPU设备上工作?

为什么 python 解释器不能在我的任何笔记本的 Zeppelin 0.8.0 上工作?

为什么 div 表不能在使用 WAMP 服务的网站上的 Firefox 上工作?

为什么这个 3d css 动画不能在移动设备上工作?

为什么悬停不能在包含另一个div的div上工作?

为什么硒不能在我的浏览器上工作?

为什么我的 flexbox 不能在最新的 chrome 版本上工作?

为什么我不能在包外使用受保护的构造函数?

为什么不能在与受保护类型相同的程序包中声明共享变量?

为什么 Objective-C 不能在受保护的函数指针中使用“self”对象?