@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 进行操作。