Spring Boot项目中UserService注入失败及空指针问题求助
问题
开发Spring Boot个人项目时遇到两类问题:
- 使用构造函数注入时,报错:
com.learningapp.backend.AcademixHub.services.UserService的构造函数参数2需要的com.learningapp.backend.AcademixHub.mappers.UserMapper类型Bean无法找到; - 移除成员变量的
final修饰符并添加默认构造函数后,服务可正常启动,但调用注册接口时触发NullPointerException,提示this.userRepository为null。
UserService.java
@Service public class UserService { private final UserRepository userRepository; private final PasswordEncoder passwordEncoder; private final UserMapper userMapper; public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, UserMapper userMapper) { super(); this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; this.userMapper = userMapper; } public UserDto register(SignUpDto signupDto) { System.out.println("hello man hi hello"); Optional<User> optionalUser = userRepository.findByEmail(signupDto.getEmail()); if (optionalUser.isPresent()) { throw new AppException("Login already exists", HttpStatus.BAD_REQUEST); } User user = userMapper.signUpToUser(signupDto); user.setPassword(passwordEncoder.encode(signupDto.getPassword())); User savedUser = userRepository.save(user); return userMapper.toUserDto(savedUser); } public UserDto login(LoginDto loginDto) { User user = userRepository.findByEmail(loginDto.getEmail()) .orElseThrow(() -> new AppException("Unknown user", HttpStatus.NOT_FOUND)); if (passwordEncoder.matches(loginDto.getPassword(), user.getPassword())) { return userMapper.toUserDto(user); } throw new AppException("Invalid password", HttpStatus.BAD_REQUEST); } public UserDto findByEmail(String login) { User user = userRepository.findByEmail(login) .orElseThrow(() -> new AppException("Unknown user", HttpStatus.NOT_FOUND)); return userMapper.toUserDto(user); } }
UserMapper.java
@Mapper(componentModel="spring") @Component public interface UserMapper { UserDto toUserDto(User user); @Mapping(target = "password", ignore = true) User signUpToUser(SignUpDto signUpDto); }
解决方案
1. 修复UserMapper Bean无法找到的问题
- 删掉
UserMapper接口上的@Component注解。MapStruct的@Mapper(componentModel="spring")已经会自动生成带有@Component的实现类,重复添加会导致Spring无法识别正确的Bean实例。 - 确认项目依赖配置正确:
- Maven项目:在
pom.xml中确保mapstruct核心依赖和mapstruct-processor注解处理器都已配置,且processor路径正确。 - Gradle项目:在
build.gradle中把mapstruct-processor加入annotationProcessor依赖。
- Maven项目:在
- 执行项目的clean+compile操作,让MapStruct自动生成
UserMapper的实现类,Spring就能扫描到这个Bean了。
2. 解决NullPointerException问题
添加默认构造函数后,Spring会用无参构造创建UserService实例,不会执行带参构造注入依赖,导致userRepository等变量为空。解决核心是回到构造函数注入的正确方式:
- 先解决上面的
UserMapperBean问题,确保所有依赖(UserRepository、PasswordEncoder、UserMapper)都能被Spring找到。 - 保留成员变量的
final修饰符和带参构造函数,Spring会自动通过构造函数注入所有依赖,避免空指针。
另外可以用Lombok的@RequiredArgsConstructor注解简化代码:给UserService类添加这个注解,它会自动为所有final成员变量生成构造函数,省去手动编写构造函数的麻烦,同时保证依赖注入正常工作(记得先引入Lombok依赖)。
内容的提问来源于stack exchange,提问作者anik
相关产品推荐
相关产品推荐

