【发布时间】:2017-06-30 08:16:31
【问题描述】:
我的情况是这样的:
我正在构建一个 Spring Boot 应用程序,当我在控制器中自动装配 UserRepository 时,它会对其进行初始化,当我尝试调用 findByUserName 方法时,一切正常。
用户控制器
@Controller
@RequestMapping(path="/api/v1/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping(path="/{userName}")
public @ResponseBody AuthenticationDetails getUserByUsername(@PathVariable String userName) throws UserNotFoundException {
User user = userRepository.findByUserName(userName);=
...
}
}
创建控制器后,我需要使用 Spring Security 来保护控制器的路径,因此我在 SecurityConfig 类中添加了以下配置:
安全配置
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, "/login").permitAll().anyRequest().authenticated().and()
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new JWTAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
...
}
现在,当我尝试向 /login 路径发布请求时,当我尝试通过调用 findByUserName 方法通过 userRepository 实例加载数据时,我在 CustomAuthenticationProvider 类中收到 NullPointerException,因为 userRepository 实例为空。
CustomAuthenticationProvider
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UserRepository userRepository;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
User userFromRepository = userRepository.findByUserName(authentication.getName().toLowerCase());
...
}
我的问题是这样的:
在应用程序运行期间,bean 的状态是否相同?应用程序加载时创建的 bean 是否正确?
为什么 Spring Boot 设法在我的控制器和同一个应用程序中使用 bean 自动装配实例,但在另一个类中却不自动装配它们?
【问题讨论】:
-
请出示您的userRepository代码。几乎可以肯定您在那里缺少 @Repository 注释,因此 Spring 没有要自动装配的 bean
-
正如我最初所说的,当我在控制器中自动装配它时它会起作用,因此@Repository 注释存在
-
只是我想也许你像
new CustomAuthenticationProvider()一样创建它,所以它不是一个spring bean,也不是由spring 上下文管理的。在这种情况下,@Autowire显然是行不通的 -
是的!这就是问题所在。我有完全相同的问题。使用 new 创建实例时,Autowired 不起作用
-
当然。这行不通。你的
CustomAuthenticationProvider应该是一个spring bean,所以它的文件可以被注入
标签: java spring spring-boot autowired