从上一个私有方法春天在什么@Transactional属性的工作?
使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释对受保护的,私有的或程序包可见的方法进行注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。
我可以想到排除private
和package-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
方法的行为就像公共方法(即,通过代理),只是设计上忽略了交易性。
因为这:
在代理模式(默认)下,将仅拦截通过代理传入的“外部”方法调用。这意味着即使调用的方法标记有@Transactional,“自调用”(即目标对象内的方法调用目标对象的其他方法)也不会在运行时导致实际事务!
和这个:
由于Spring的AOP框架基于代理的性质,从定义上讲,无论是JDK代理(不适用)还是CGLIB代理(在技术上可行,但不建议用于AOP的目的),都不会拦截受保护的方法。结果,任何给定的切入点将仅与公共方法匹配!
Spring的家伙可能希望与JDK代理保持一致。您不希望基于JDK和CGLIB具有不同的代理配置和不同的结果。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句