@Validated

时间:2018-03-02 16:14:38

标签: spring validation transactions aop spring-aspects

如果我将@Validated注释添加到我的服务的接口/实现中,那么该服务不再是事务性的。 Stacktrace显示没有TransactionInterceptor,但我只看到MethodValidationInterceptor。如果我删除@Validated,那么我看到TransactionInterceptorMethodValidationInterceptor当然会消失。这些方面是否相互排斥?

@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 {..}

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:5)

已解决

当服务使用@Transactional接口注入自己的代理时,

@ValidatedApplicationContextAware无法协同工作,如下所示:

  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()方法在后期处理阶段由ApplicationContextAwareProcessor MethodValidationPostProcessor@Validated)和AnnotationAwareAspectJAutoProxyCreator调用(@Transactional@Aspects)将原始bean包装到代理实例中。

在此过程中调用getBean()方法会导致bean无法完全初始化,因为某些后处理操作未应用。在我的情况下,TransactionInterceptor没有被添加。

enter image description here

为了向服务注入自己的代理,我最终使用LOWEST_PRECEDENCE创建了专门的Ordered BeaNPostProcessor,以确保我在完全初始化的bean上运行。