gpt4 book ai didi

java - Spring boot 2 @Transactional 注释使 Autowired 字段为空

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:56 24 4
gpt4 key购买 nike

我正在尝试在我的服务方法中使用 @Transactional 注释来延迟加载字段。但是,在我的实现类上使用 @Transactional 会使所有 Autowiring 的字段都为 null

这是我的实现:

@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;
}

提前谢谢你。

最佳答案

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

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

  1. 从你的方法中移除final
  2. 通过将 spring.aop.proxy-target-class=false 添加到您的 application.properties 来禁用基于类的代理

现在,当您添加 @Transactional 时,这将导致创建您的 UserServiceImpl 的代理,确切地说是基于类的代理。发生的情况是为您的 UserServiceImpl 创建了一个子类,并且所有方法都被覆盖以应用 TransactionInterceptor。但是,由于您的方法被标记为 final,因此动态创建的类无法覆盖此方法。因此,该方法查看动态创建的代理类中的字段实例,该实例始终为 null

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

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

关于java - Spring boot 2 @Transactional 注释使 Autowired 字段为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44881890/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com