spring - 为什么配置类会与自身形成循环依赖?
问题描述
我不明白这个类本身产生循环依赖注入的原因是什么。我尝试添加 @Lazy 注释或从构造函数中删除 @Autowired ,但它没有帮助。房间里可能有一头我没看到的大象。
这是控制台显示的内容:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| securityConfiguration defined in file [E:\Users\Adelin\eclipse-workspace2\AuthenticationSpringJWTAngular\target\classes\src\main\configuration\SecurityConfiguration.class]
这是配置类:
package src.main.configuration;
import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;
import static src.main.constant.SecurityConstant.PUBLIC_URLS;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import src.main.filter.JWTAccessDeniedHandler;
import src.main.filter.JWTAuthenticationEntryPoint;
import src.main.filter.JWTAuthorizationFilter;
import src.main.service.IUserDetailsService;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
private JWTAuthorizationFilter jwtAuthorizationFilter;
private JWTAccessDeniedHandler jwtAccessDeniedHandler;
private JWTAuthenticationEntryPoint jwtAuthenticationEntryPoint;
private IUserDetailsService userDetailsService;
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Autowired
public SecurityConfiguration(JWTAuthorizationFilter jwtAuthorizationFilter,
JWTAccessDeniedHandler jwtAccessDeniedHandler, JWTAuthenticationEntryPoint jwtAuthenticationEntryPoint,
IUserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder) {
this.jwtAuthorizationFilter = jwtAuthorizationFilter;
this.jwtAccessDeniedHandler = jwtAccessDeniedHandler;
this.jwtAuthenticationEntryPoint = jwtAuthenticationEntryPoint;
this.userDetailsService = userDetailsService;
this.bCryptPasswordEncoder = bCryptPasswordEncoder;
}
@Override
protected void configure(AuthenticationManagerBuilder amb) throws Exception {
amb.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()//
.cors().and() //
// we're not using sessions, not keeping track of currently logging in users
// users prove by using a token -> stateless
.sessionManagement().sessionCreationPolicy(STATELESS).and() //
.authorizeRequests().antMatchers(PUBLIC_URLS).permitAll() // no authentication
// needed
.anyRequest().authenticated().and() // anything else - reqs. authentication
.exceptionHandling().accessDeniedHandler(jwtAccessDeniedHandler)
.authenticationEntryPoint(jwtAuthenticationEntryPoint).and()
.addFilterBefore(jwtAuthorizationFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
}
解决方案
我怀疑是因为这个
的构造函数SecurityConfiguration
标@Autowired
有一个类型的参数,BCryptPasswordEncoder
所以基本上为了实例化SecurityConfiguration
它需要一个类型的 bean BCryptPasswordEncoder
。
但话又说回来,同一个类有一个实例方法,它正在创建 type 的 bean BCryptPasswordEncoder
。
所以基本上,构造函数不能被调用,因为它依赖于方法返回的值,而方法不能被调用,因为构造函数还没有被调用来实例化它。
如果您将方法更改为以下(我并不是建议将其作为解决方案,而只是为了验证我的理解),那么它可能会起作用。
@Bean
public static BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
推荐阅读
- javascript - React/React-Native 最高效的 onChange 订阅方式
- python - Module not found error Kivy Python 3.6 Mac OS High Sierra
- rust - Lifetimes for method returning iterator of structs with same lifetime
- ios - On Demand Resource AppStore Upload Failure in iOS application - Disallowed Paths
- python - 排序后修剪字典的最佳方法是什么?
- android - TabLayout 中的嵌套片段不正确的布局膨胀
- angular5 - 如何修复Angular Material 2中mat-table水平滚动中的单列
- node.js - fiber@1.0.15 安装 node_modules/fibers 节点 build.js || nodejs build.js
- salt-stack - 我如何知道我的 salt-call 使用的是什么静态配置文件?
- mysql - java.sql.SQLException:ResultSet 来自 UPDATE。没有数据。对于所有查询