@Transactional 在@Validated 时不起作用
@Transactional does not work when @Validated
如果我向服务的 interface/implementation 添加 @Validated
注释,则该服务不再是事务性的。 Stacktrace 显示没有 TransactionInterceptor
,但我只看到 MethodValidationInterceptor
。如果我删除 @Validated
然后我看到 TransactionInterceptor
并且 MethodValidationInterceptor
当然消失了。这些方面是否相互排斥?
@Service
//@Validated <- here is my problem :)
public interface AdminService {
String test(String key, String result);
}
public class AdminServiceImpl implements AdminService, BeanNameAware, ApplicationContextAware {
@Override
@Transactional(transactionManager = "transactionManager")
public String test(String key, String result) {
return "hehe";
}
}
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableTransactionManagement(order = AspectPrecedence.TRANSACTION_MANAGEMENT_ORDER)
public class AppConfiguration {..}
已解决
@Transactional
和 @Validated
当服务通过使用 ApplicationContextAware
接口注入自己的代理时不能一起工作,如下所示:
private String beanName;
private AdminService self;
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
self = applicationContext.getBean(beanName, AdminService.class);
}
在调试过程中,我注意到 setApplicationContext()
方法在 post 处理阶段被 ApplicationContextAwareProcessor
调用,其中 MethodValidationPostProcessor
(@Validated
)和 AnnotationAwareAspectJAutoProxyCreator
(@Transactional
和 @Aspects
)将原始 bean 包装到代理实例中。
在此过程中调用 getBean()
方法导致 bean 未完全初始化,因为某些 post 处理操作未应用。在我的例子中 TransactionInterceptor
没有被添加。
为了将自己的代理注入服务,我最终创建了使用 LOWEST_PRECEDENCE
执行的专用 Ordered BeaNPostProcessor,以确保我对完全初始化的 bean 进行操作。
如果我向服务的 interface/implementation 添加 @Validated
注释,则该服务不再是事务性的。 Stacktrace 显示没有 TransactionInterceptor
,但我只看到 MethodValidationInterceptor
。如果我删除 @Validated
然后我看到 TransactionInterceptor
并且 MethodValidationInterceptor
当然消失了。这些方面是否相互排斥?
@Service
//@Validated <- here is my problem :)
public interface AdminService {
String test(String key, String result);
}
public class AdminServiceImpl implements AdminService, BeanNameAware, ApplicationContextAware {
@Override
@Transactional(transactionManager = "transactionManager")
public String test(String key, String result) {
return "hehe";
}
}
@Configuration
@EnableAspectJAutoProxy(exposeProxy = true)
@EnableTransactionManagement(order = AspectPrecedence.TRANSACTION_MANAGEMENT_ORDER)
public class AppConfiguration {..}
已解决
@Transactional
和 @Validated
当服务通过使用 ApplicationContextAware
接口注入自己的代理时不能一起工作,如下所示:
private String beanName;
private AdminService self;
@Override
public void setBeanName(String beanName) {
this.beanName = beanName;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
self = applicationContext.getBean(beanName, AdminService.class);
}
在调试过程中,我注意到 setApplicationContext()
方法在 post 处理阶段被 ApplicationContextAwareProcessor
调用,其中 MethodValidationPostProcessor
(@Validated
)和 AnnotationAwareAspectJAutoProxyCreator
(@Transactional
和 @Aspects
)将原始 bean 包装到代理实例中。
在此过程中调用 getBean()
方法导致 bean 未完全初始化,因为某些 post 处理操作未应用。在我的例子中 TransactionInterceptor
没有被添加。
为了将自己的代理注入服务,我最终创建了使用 LOWEST_PRECEDENCE
执行的专用 Ordered BeaNPostProcessor,以确保我对完全初始化的 bean 进行操作。