Spring Boot:Autowired CRUDRepository null,在某些类中
Posted
技术标签:
【中文标题】Spring Boot:Autowired CRUDRepository null,在某些类中【英文标题】:Spring Boot: Autowired CRUDRepository null, in certain classes 【发布时间】:2017-09-03 20:11:24 【问题描述】:我正在运行一个 SpringBoot 应用程序,其根类使用 @SpringBootApplication
、@EnableAutoConfiguration
进行注释。
我创建了一个UserRepositoryInterface
接口,它扩展 CrudRepository
接口与我的用户JPA 对象。这个接口没有实现,也不需要一个。此应用程序中也没有任何配置文件。 JPA DB 连接除外,但它有效。
public interface UsersRepositoryInterface extends CrudRepository<User, Long>
// Query to search for users via email
List<User> findByEmail(@Param("email") String email);
我已经成功地将它自动连接到一些 REST 端点中。当我尝试将其自动装配到我的安全类中时,问题就出现了。我正在尝试使用 JWT 进行身份验证,它可以工作。现在我想在登录过程中调用数据库,但我遇到了问题。以下是课程:
首先是WebSecurityConfiguererAdapter
类,我在其中添加了过滤器的路径。请注意带有“new JWTLoginFilter
”的行,这是我尝试自动装配的类:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
private CustomUserDetailsService userDetailsServ;
@Override
protected void configure(HttpSecurity http) throws Exception
http.csrf().disable().authorizeRequests()
//Allow options pre-flight request
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
// Allow POST request to /login
.antMatchers(HttpMethod.POST, "/login").permitAll()
// Others must be authenticated
.anyRequest().authenticated()
.and()
// We filter the api/login requests
.addFilterBefore(new JWTLoginFilter("/login", authenticationManager()),
UsernamePasswordAuthenticationFilter.class)
// And filter other requests to check the presence of JWT in header
.addFilterBefore(new JWTAuthenticationFilter(),
UsernamePasswordAuthenticationFilter.class);
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
// Change logging in from username+password to email+password
auth.userDetailsService(userDetailsServ);
还有JWTLoginFilter
类。我省略了一些不相关的代码:
public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter
@Autowired
private UsersRepositoryInterface userRepo;
public JWTLoginFilter(String url, AuthenticationManager authManager)
super(new AntPathRequestMatcher(url));
setAuthenticationManager(authManager);
@Override
public Authentication attemptAuthentication(
HttpServletRequest req, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException
//Check if userRepo is injected
if(userRepo == null)
System.out.println("Null");
AccountCredentials creds = new ObjectMapper()
.readValue(req.getInputStream(), AccountCredentials.class);
return getAuthenticationManager().authenticate(
new UsernamePasswordAuthenticationToken(
creds.getEmail(),
creds.getPassword(),
Collections.emptyList()
)
);
JWTLoginFilter
中的 println
在被调用时将始终返回 Null。
我错过了什么吗?
解决了:
现在工作。
用
注释JWTLoginFilter@Component("someName")
并使用
将其注入 WebSecurityConfig@Resource(name="someName")
private JWTLoginFilter myFilter;
在 JWTLoginFilter 构造函数中硬编码 URL,但我仍然必须将 AuthenticationManager 从 WebSecurityConfig 自动连接到 JWTLoginFilter。
首先必须使 AuthenticationManager 成为一个 Bean。在这里使用了答案:How To Inject AuthenticationManager using Java Configuration in a Custom Filter
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
然后在这里注入答案:Spring Security authenticationmanager must be specified - for custom filter
@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager)
super.setAuthenticationManager(authenticationManager);
同时删除
setAuthenticationManager(authManager);
在 JWTLoginFilter 的构造函数中
【问题讨论】:
能否请您添加您的项目结构? 相关***.com/questions/36663048/… 【参考方案1】:嗯,你期待什么?您正在通过 new
关键字创建 JWTLoginFilter
。 Spring 在这里根本不做任何布线。您应该将此过滤器设置为@Bean
或@Component
或其他任何使其成为spring bean
并以某种方式将其注入WebSecurityConfig
的方法。
【讨论】:
我对 Spring 很陌生,所以我不知道。有趣的。我有点被愚弄了,但我似乎无法将 JWTLoginFilter 类注入 WebSecurityConfig。有什么建议吗? 相关回答***.com/questions/36663048/…【参考方案2】:我希望您的问题已经得到解决。但是我添加了一个示例代码 sn-p 供遇到相同问题的人参考。
当我们的过滤器包含自动装配的依赖项时,并且在 spring 配置中使用 new() 实例化我们的过滤器不会自动装配它的依赖项,因为这不是一个字符串管理的 bean。因此,我们需要在 spring 应用程序配置类中自动装配我们的过滤器,从而自动装配其内部依赖项。
PFB示例代码供参考。
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer
@Autowired
private MyFilter myFilter;
public static void main(String[] args)
SpringApplication.run(MyApplication.class, args);
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)
return builder.sources(MyApplication.class);
@Bean
public FilterRegistrationBean myFilterRegistration()
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(myFilter);
registration.addUrlPatterns("*");
return registration;
过滤器:
@Component
public class MyFilter extends BaseFilter
@Autowired
private EmployeeRepository employeeRepository;
//your code goes here
if(employeeRepository != null)
System.out.println("employeeRepository is not null");
【讨论】:
以上是关于Spring Boot:Autowired CRUDRepository null,在某些类中的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Boot 类之间正确注入 @Autowired?
spring-boot Autowired DiscoveryClient RestTemplate UnknownHostException
单元测试中的 Spring Boot @Autowired 返回 NullPointerException