2017-07-03 99 views
5

我试图在我的服务的方法中使用@Transactional注释来延迟加载字段。然而,在我的Implementation类中使用@Transactional将使所有自动装配字段nullSpring引导2 @Transactional注释使得Autowired字段为空

这是我实现:

@Service 
public class UserServiceImpl implements UserService { 

/** 
    * DefaultMapper. 
    */ 
@Autowired 
private DefaultMapper defaultMapper; 

/** 
    * Resource service injection. 
    */ 
@Autowired 
private ResourceService resourceService; 

/** 
    * UserRepository. 
    */ 
@Autowired 
private UserRepository userRepository; 

/** 
    * Jwt Factory. 
    */ 
@Autowired 
private JwtService jwtService; 

@Override 
@Transactional 
public final UserDto findByLogin(final String login) throws ResourceNotFoundException { 
// user repository is null here when using @Transactional 
    User user = this.userRepository.findByLogin(login) 
    .orElseThrow(() -> new ResourceNotFoundException(
    resourceService.getMessage(MessageBundle.EXCEPTION, "resource.notfound.user.login") 
    )); 
    UserDto userDto = defaultMapper.asUserDtoWithRoles(user); 
    return userDto; 
} 

预先感谢您。

+3

从你的方法中删除'final'或者在'application.properties'中设置'spring.aop.proxy-target-class = false'。 **注意:**这需要Spring Boot 1.5.3或完全正常工作! –

+0

在你的spring应用程序中启用了事务上下文吗? – drgPP

+0

在阅读行为中,大部分时间进行交易是无用的,你确定你需要阅读交易吗? – Zorglube

回答

5

使用AOP应用事务等,Spring中的默认AOP机制是使用代理。当使用Spring Boot时,代理模式被设置为基于类的代理。

您可以通过2种方法之一解决此问题。

  1. 加入spring.aop.proxy-target-class=falseapplication.properties

现在,当您交锋@Transactional这将导致你的UserServiceImpl的代理从你的方法删除final

  • 禁用基于类的代理被创建,一类基于代理的准确。会发生什么是为您的UserServiceImpl创建了一个子类,并且覆盖了所有方法以应用TransactionInterceptor。但是,由于您的方法被标记为final,动态创建的类不能重写此方法。因此,该方法将查看动态创建的代理类中的字段实例,该代理类始终为null

    当删除final该方法可以被覆盖,应用的行为,它会查看适当的字段实例(实际UserServiceImpl而不是代理)。

    禁用基于类的代理时,您将获得一个JDK动态代理,它基本上是一个实现您的服务实现的所有接口的薄包装器。它应用添加的行为(事务)并调用实际的服务。没有实际类所需的扩展,因此您可以代理最终方法(只要它是您的接口的一部分)。

  • 相关问题