Spring 数据存储库无法自动装配
Spring Data repository can't autowire
我正在从头开始创建一个新的 Spring 启动应用程序,并想为其编写测试。我刚刚在我的应用程序中实现了身份验证,想了解角色的工作原理。
当我在身份验证过程中使用我的 UserRepository 时,一切正常。但是,当我想在测试中使用 UserRepository 时,它说该对象为 null,与我在应用程序代码中使用它时相同。这是为什么?
这是代码。
安全配置class:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PowderizeUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout().permitAll();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManager) {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(passwordEncoder());
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationManager.authenticationProvider(authenticationProvider);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
用户class:
@Entity
@Table(name = "USERS")
@NoArgsConstructor
@Getter
public class User extends BaseEntity {
private String firstName;
private String lastName;
private String emailAddress;
private String nickname;
private String password;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
@ManyToMany(mappedBy = "users_roles")
private Set<Role> roles;
}
存储库:
public interface UserRepository extends CrudRepository<User, Long> {
public Optional<User> findByEmailAddress(String email);
}
UserDetailsService 实现 class,使用存储库没有问题:
@Service
public class PowderizeUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return new PowderizePrincipal(
userRepository.findByEmailAddress(email)
.orElseThrow(() -> new UsernameNotFoundException("User '" + email + "' not found."))
);
}
}
并且测试 class returns NullPointerException:
@SpringBootTest
public class UsersAndRolesTest {
@Autowired
private UserRepository userRepository;
@Test
public void ww(){
assertThat(userRepository, notNullValue());
}
@Test
public void userExistsInDatabase(){
assertThat(userRepository.findByEmailAddress("admin@mail.com").isPresent(), notNullValue());
}
}
我尝试过使用像@Repository、@EnableJpaRepositories 这样的注解,实际上我找到了所有的解决方案。 IntelliJ 还突出显示 userRepository
和 "Could not autowire. No beans of 'UserRepository' type found."
将此注释添加到您的 UsersAndRolesTest class
@RunWith(SpringRunner.class)
在 vanillaSugar 的回答的指导下,我找到了解决方案。我缺少的是 @RunWith(SpringRunner.class)
注释,但这还不够。我意识到问题也与测试套件所在的包有关。我没有在问题中添加 package
行代码,这也是问题的一部分。
根据我的发现,@SpringBootApplication
会在应用程序的包层次结构中扫描其下方的组件。只是添加 @RunWith
注释导致我遇到了这个问题,但有另一个例外:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
。
我还必须做的是将我的测试 class 从以前的包 - security.UsersAndRolesTest
移动到 com.powderize.security.UsersAndRolesTest
,"mirrors" 应用程序代码中的包。对于更高级的 Spring 开发人员来说可能很明显,但我花了一段时间才发现它。
我正在从头开始创建一个新的 Spring 启动应用程序,并想为其编写测试。我刚刚在我的应用程序中实现了身份验证,想了解角色的工作原理。
当我在身份验证过程中使用我的 UserRepository 时,一切正常。但是,当我想在测试中使用 UserRepository 时,它说该对象为 null,与我在应用程序代码中使用它时相同。这是为什么? 这是代码。
安全配置class:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PowderizeUserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/login").permitAll()
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.logout().permitAll();
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManager) {
DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
authenticationProvider.setPasswordEncoder(passwordEncoder());
authenticationProvider.setUserDetailsService(userDetailsService);
authenticationManager.authenticationProvider(authenticationProvider);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
}
用户class:
@Entity
@Table(name = "USERS")
@NoArgsConstructor
@Getter
public class User extends BaseEntity {
private String firstName;
private String lastName;
private String emailAddress;
private String nickname;
private String password;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
@ManyToMany(mappedBy = "users_roles")
private Set<Role> roles;
}
存储库:
public interface UserRepository extends CrudRepository<User, Long> {
public Optional<User> findByEmailAddress(String email);
}
UserDetailsService 实现 class,使用存储库没有问题:
@Service
public class PowderizeUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
return new PowderizePrincipal(
userRepository.findByEmailAddress(email)
.orElseThrow(() -> new UsernameNotFoundException("User '" + email + "' not found."))
);
}
}
并且测试 class returns NullPointerException:
@SpringBootTest
public class UsersAndRolesTest {
@Autowired
private UserRepository userRepository;
@Test
public void ww(){
assertThat(userRepository, notNullValue());
}
@Test
public void userExistsInDatabase(){
assertThat(userRepository.findByEmailAddress("admin@mail.com").isPresent(), notNullValue());
}
}
我尝试过使用像@Repository、@EnableJpaRepositories 这样的注解,实际上我找到了所有的解决方案。 IntelliJ 还突出显示 userRepository
和 "Could not autowire. No beans of 'UserRepository' type found."
将此注释添加到您的 UsersAndRolesTest class
@RunWith(SpringRunner.class)
在 vanillaSugar 的回答的指导下,我找到了解决方案。我缺少的是 @RunWith(SpringRunner.class)
注释,但这还不够。我意识到问题也与测试套件所在的包有关。我没有在问题中添加 package
行代码,这也是问题的一部分。
根据我的发现,@SpringBootApplication
会在应用程序的包层次结构中扫描其下方的组件。只是添加 @RunWith
注释导致我遇到了这个问题,但有另一个例外:
java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test
。
我还必须做的是将我的测试 class 从以前的包 - security.UsersAndRolesTest
移动到 com.powderize.security.UsersAndRolesTest
,"mirrors" 应用程序代码中的包。对于更高级的 Spring 开发人员来说可能很明显,但我花了一段时间才发现它。