Spring Repository无法在Configuration类中实例化/自动装配求助
问题重现
在开发集成JWT安全机制的项目时,编写完配置类后出现编译错误,相关代码及错误信息如下:
ApplicationConfig代码
@Configuration @RequiredArgsConstructor public class ApplicationConfig { private final UserRepository repository; @Bean public UserDetailsService userDetailsService() { return username -> repository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User not found")); } @Bean public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); authProvider.setUserDetailsService(userDetailsService()); authProvider.setPasswordEncoder(passwordEncoder()); return authProvider; } @Bean public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception { return config.getAuthenticationManager(); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } }
编译错误
ApplicationConfig.java:21: error: variable userRepository not initialized in the default constructor private final UserRepository userRepository; ^
其他相关代码
UserRepository
@Repository public interface UserRepository extends JpaRepository<User, Integer> { Optional<User> findByUsername(String username); }
启动类
@SpringBootApplication @EnableConfigurationProperties(ConfigProperties.class) @EnableJpaRepositories("com.browna.teller_back.repositories") public class TellerBackApplication { public static void main(String[] args) { SpringApplication.run(TellerBackApplication.class, args); } }
User实体类
@Builder @Entity @Table(name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = "username"), @UniqueConstraint(columnNames = "email") }) public class User implements UserDetails { @Getter @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id; @NotBlank @Size(max = 20) private String username; @NotBlank @Size(max = 50) @Email private String email; @NotBlank @Size(max = 120) private String password; @Enumerated(EnumType.STRING) private Role role; public User() { } public User(String username, String email, String password) { this.username = username; this.email = email; this.password = password; } public @NotBlank @Size(max = 20) String getUsername() { return username; } }
错误分析与解决方案
1. 变量名不一致(核心问题)
错误提示的是userRepository未初始化,但你提供的ApplicationConfig里变量名是repository——这说明你实际代码中可能把变量名写成了userRepository,但@RequiredArgsConstructor没有正确生成对应构造函数,或者变量未被正确注入。
修复步骤:
确保ApplicationConfig中的Repository变量名统一,且@RequiredArgsConstructor能生成构造函数:
@Configuration @RequiredArgsConstructor public class ApplicationConfig { // 变量名与错误提示一致,确保@RequiredArgsConstructor生成带该参数的构造函数 private final UserRepository userRepository; // 后续代码中调用该变量时也要同步修改 @Bean public UserDetailsService userDetailsService() { return username -> userRepository.findByUsername(username) .orElseThrow(() -> new UsernameNotFoundException("User not found")); } // ... 其他代码 }
@RequiredArgsConstructor会自动为所有final字段生成构造函数,Spring会通过构造函数注入UserRepository实例。
2. 确认UserRepository被Spring扫描到
启动类添加了@EnableJpaRepositories("com.browna.teller_back.repositories"),需确保UserRepository接口确实位于该包(或其子包)下,否则Spring无法创建它的代理实例,导致注入失败。
3. 检查依赖完整性
确保项目依赖中包含Spring Data JPA:
- Maven(pom.xml):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
- Gradle(build.gradle):
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
缺少该依赖的话,Spring无法识别@Repository注解和JpaRepository接口。
4. 替代注入方案(如果构造函数注入仍有问题)
如果@RequiredArgsConstructor不好用,可以手动用构造函数注入:
@Configuration public class ApplicationConfig { private final UserRepository userRepository; // 显式添加构造函数,Spring会自动注入参数 public ApplicationConfig(UserRepository userRepository) { this.userRepository = userRepository; } // ... 其他代码 }
或者使用@Autowired(不推荐,但可临时排查问题):
@Configuration public class ApplicationConfig { @Autowired private UserRepository userRepository; // ... 其他代码 }
注意:使用@Autowired时变量不能是final类型。
额外提示
你的User实体实现了UserDetails接口,需确保重写所有必要方法(如isAccountNonExpired()、isAccountNonLocked()等),否则后续Spring Security运行时会抛出异常。
内容的提问来源于stack exchange,提问作者Aluxxen

