![](/img/trans.png)
[英]Error in Spring bean injection : leads to a NullPointerException
[英]Spring Injection of JPA Repository bean is not working - NullPointerException
我正在尝试将由 Spring 管理和实现的 JPA 存储库注入到服务 class 中。 但是在运行时程序在第 39 行抛出 NPE。
这是我的服务 class:
@Service
public class RegistrationFormProcessor {
private ContractorRepository contractorRepository;
private AddressRepository addressRepository;
private UserRepository userRepository;
private PasswordEncoder passwordEncoder;
@Autowired
public RegistrationFormProcessor(ContractorRepository contractorRepository, AddressRepository addressRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.contractorRepository = contractorRepository;
this.addressRepository = addressRepository;
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
public User prepareUser(RegistrationForm registrationForm) {
Address address = new Address(
registrationForm.getCountry(),
registrationForm.getCity(),
registrationForm.getStreet(),
registrationForm.getZipCode(),
registrationForm.getProperty()
);
Address savedAddress = addressRepository.save(address); // line 39
Contractor userCompany = new Contractor(
registrationForm.getCompanyName(),
registrationForm.getShortName(),
savedAddress,
registrationForm.getNip(),
registrationForm.getRegon(),
registrationForm.getPhone(),
registrationForm.getEmail(),
registrationForm.getWebsite()
);
Contractor savedUserCompany = contractorRepository.save(userCompany); // line 51
User user = new User(
registrationForm.getFirstName(),
registrationForm.getLastName(),
registrationForm.getLastName(),
passwordEncoder.encode(registrationForm.getPassword()),
"ROLE_USER",
true,
savedUserCompany
);
User savedUser = userRepository.save(user);
savedUserCompany.setOwner(savedUser);
contractorRepository.save(savedUserCompany);
return savedUser;
}
AddressRepository 和其他字段与由 Spring 管理的接口自动连接,该接口自动实现所有方法。
import org.springframework.data.repository.CrudRepository;
public interface AddressRepository extends CrudRepository <Address, Long> {}
就我而言,RegistrationFormProcessor 的实例是由 Spring 管理的实例(至少我希望如此)。 RegistrationFormProcessor 被注释@Service
并被注入 controller class 之一。 在那里使用它并且程序抛出提到的异常。 在 controller 下方:
@Controller
@RequestMapping("/register")
public class RegistrationController {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@GetMapping
public String registerForm(Model model) {
model.addAttribute("registrationForm", new RegistrationForm());
return "register/registration";
}
@PostMapping
public String processRegistrationForm(RegistrationForm form, @Autowired RegistrationFormProcessor registrationFormProcessor) {
registrationFormProcessor.prepareUser(form);
return "redirect:/login";
}
}
如果删除第 39 行,程序将在第 51 行处理 NPE(如果userRepository.save(user)
,则依此类推)。 在这些行中,应该使用由 Spring-data 自动实现的save()
等方法的存储库。
我在 controller 类中有类似的注入(也在构造函数中),并且一切正常。
我做错了什么? 为什么在服务中 class Spring 不注入这些依赖项和字段是 null? 我尝试设置断点并调试 - 确认字段为null
。 正如我上面所说的,在其他被注释为@Controller
的类中,同样的字段也注入到构造函数中,它们不是空值,并且一切正常。
试图将接口 AddresRepository 注释为@Repository
但它不起作用。 另一方面,对于 Spring - Spring 没有必要确保在控制器中正确实施方法。
提前感谢您的任何建议。
您可以删除 @Autowired 注释并将 final 关键字添加到存储库定义中,如下所示:
private final ContractorRepository contractorRepository;
private final AddressRepository addressRepository;
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public RegistrationFormProcessor(ContractorRepository contractorRepository, AddressRepository addressRepository, UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.contractorRepository = contractorRepository;
this.addressRepository = addressRepository;
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
您应该尝试为您的存储库添加final
关键字以进行注入,如下所示:
private final ContractorRepository contractorRepository;
private final AddressRepository addressRepository;
...
通过将 controller 中的 RegistrationFormProcessor 注入从 controller 方法中的注入作为参数声明为字段并在 controller 字段中注入来解决问题。
前
@Controller
@RequestMapping("/register")
public class RegistrationController {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
}
@PostMapping
public String processRegistrationForm(RegistrationForm form, @Autowired RegistrationFormProcessor registrationFormProcessor) {
registrationFormProcessor.prepareUser(form); // throws NPE - not working
return "redirect:/login";
}
}
后:
@Controller
@RequestMapping("/register")
public class RegistrationController {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final RegistrationFormProcessor registrationFormProcessor;
public RegistrationController(UserRepository userRepository, PasswordEncoder passwordEncoder, RegistrationFormProcessor registrationFormProcessor) {
this.userRepository = userRepository;
this.passwordEncoder = passwordEncoder;
this.registrationFormProcessor = registrationFormProcessor;
}
@PostMapping
public String processRegistrationForm(RegistrationForm form) {
registrationFormProcessor.prepareUser(form); //working fine
return "redirect:/login";
}
}
但无法解释为什么...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.