Spring Boot UnsatisfiedDependencyException 创建名称为无法解析的循环引用的 bean 时出错
Posted
技术标签:
【中文标题】Spring Boot UnsatisfiedDependencyException 创建名称为无法解析的循环引用的 bean 时出错【英文标题】:Spring Boot UnsatisfiedDependencyException Error creating bean with name unresolvable circular reference 【发布时间】:2021-09-14 20:39:39 【问题描述】:我正在使用 Spring Secuity 开发一个应用程序,其中有一些自定义过滤器,但我无法正确配置它们。考虑以下自定义过滤器:
LoginAuthenticationFilter:
package com.espiritware.opusclick.restfullbackend.security.filters;
public class LoginAuthenticationFilter extends OncePerRequestFilter
private static final String TOKEN_PREFIX = "Bearer ";
private static final String HEADER_STRING = "Authorization";
private String credentialsCharset = "UTF-8";
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Basic "))
filterChain.doFilter(request, response);
return;
String[] tokens = extractAndDecodeHeader(header, request);
String email = tokens[0];
String password = tokens[1];
if(request.getServletPath().equals("/login/user"))
LoginAuthenticationFilter opusClickAuth= new OpusClickLoginAuthentication(email,password,true);
try
Authentication result=authenticationManager.authenticate(opusClickAuth);
if(result.isAuthenticated())
//SecurityContextHolder.getContext().setAuthentication(result);
String jwtToken=tokenService.createAuthenticationToken(result,true);
response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + jwtToken);
response.setHeader("Content-Type", "application/json");
catch(AuthenticationException failed)
//SecurityContextHolder.clearContext();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
else
LoginAuthenticationFilter opusClickAuth= new OpusClickLoginAuthentication(email,password,false);
try
Authentication result=authenticationManager.authenticate(opusClickAuth);
if(result.isAuthenticated())
//SecurityContextHolder.getContext().setAuthentication(result);
String jwtToken=tokenService.createAuthenticationToken(result,false);
response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + jwtToken);
response.setHeader("Content-Type", "application/json");
catch(AuthenticationException failed)
//SecurityContextHolder.clearContext();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
protected String[] extractAndDecodeHeader(String header, HttpServletRequest request)
throws IOException
byte[] base64Token = header.substring(6).getBytes("UTF-8");
byte[] decoded;
try
decoded = Base64.getDecoder().decode(base64Token);
catch (IllegalArgumentException e)
throw new BadCredentialsException(
"Failed to decode basic authentication token");
String token = new String(decoded, getCredentialsCharset(request));
int delim = token.indexOf(":");
if (delim == -1)
throw new BadCredentialsException("Invalid basic authentication token");
return new String[] token.substring(0, delim), token.substring(delim + 1) ;
protected String getCredentialsCharset(HttpServletRequest httpRequest)
return this.credentialsCharset;
//No debe filtrar
//false -> se activa
//true -> no se activa
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException
if(request.getServletPath().equals("/login/user")|| request.getServletPath().equals("/login/expert"))
return false;
else
return true;
JwtAuthenticationFilter:
package com.espiritware.opusclick.restfullbackend.security.filters;
public class JwtAuthenticationFilter extends OncePerRequestFilter
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private TokenService tokenService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer "))
filterChain.doFilter(request, response);
return;
String jwtToken=extractToken(header);
JwtAuthentication jwtAuthentication = new JwtAuthentication(jwtToken);
try
Authentication result=authenticationManager.authenticate(jwtAuthentication);
SecurityContextHolder.getContext().setAuthentication(result);
filterChain.doFilter(request, response);
catch(AuthenticationException failed)
SecurityContextHolder.clearContext();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
authenticationManager.authenticate(jwtAuthentication);
protected String extractToken(String header)
int delim = header.indexOf(" ");
if (delim == -1)
throw new BadCredentialsException("Invalid authentication token");
return header.substring(delim + 1);
@Override
protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException
if(request.getServletPath().equals("/login/user")|| request.getServletPath().equals("/login/expert"))
return true;
else
return false;
过滤器配置:
package com.espiritware.opusclick.restfullbackend.security.filters.configurations;
@Configuration
public class FilterConfigurations
@Bean
public LoginAuthenticationFilter opusClickLoginAuthenticationFilter()
return new OpusClickLoginAuthenticationFilter();
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter()
return new JwtAuthenticationFilter();
WebAppSecurityConfiguration:(失败)
package com.espiritware.opusclick.restfullbackend.security;
@Configuration
public class WebAppSecurityConfiguration extends WebSecurityConfigurerAdapter
@Autowired
private LoginAuthenticationFilter opusClickLoginAuthenticationFilter;
@Autowired
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception
//http.oauth2Client();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterAt(LoginAuthenticationFilter,
BasicAuthenticationFilter.class)
.addFilterAt(jwtAuthenticationFilter,
BasicAuthenticationFilter.class);
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
// @Bean
// public LoginAuthenticationFilter LoginAuthenticationFilter()
// return new LoginAuthenticationFilter();
//
// @Bean
// public JwtAuthenticationFilter jwtAuthenticationFilter()
// return new JwtAuthenticationFilter();
//
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
当我运行应用程序时,它会抛出以下异常:
org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:163) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.8.jar:5.3.8]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.1.jar:2.5.1]
at com.espiritware.opusclick.restfullbackend.OpusClickRestfullBackendApplication.main(OpusClickRestfullBackendApplication.java:10) ~[classes/:na]
Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:450) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:199) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.5.1.jar:2.5.1]
... 8 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'LoginAuthenticationFilter': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webAppSecurityConfiguration': Unsatisfied dependency expressed through field 'jwtAuthenticationFilter'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtAuthenticationFilter': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'authenticationManagerBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:175) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:170) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:155) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:87) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234) ~[spring-boot-2.5.1.jar:2.5.1]
at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) ~[spring-boot-2.5.1.jar:2.5.1]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5161) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[na:na]
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:829) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1384) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1374) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[na:na]
at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:909) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:930) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) ~[spring-boot-2.5.1.jar:2.5.1]
... 13 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webAppSecurityConfiguration': Unsatisfied dependency expressed through field 'jwtAuthenticationFilter'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtAuthenticationFilter': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'authenticationManagerBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1334) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.8.jar:5.3.8]
... 55 common frames omitted
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jwtAuthenticationFilter': Unsatisfied dependency expressed through field 'authenticationManager'; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'authenticationManagerBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.8.jar:5.3.8]
... 78 common frames omitted
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'authenticationManagerBean': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.8.jar:5.3.8]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.8.jar:5.3.8]
... 92 common frames omitted
但是,当我评论整个 FilterConfigurations
类并直接在 WebAppSecurityConfiguration
中配置过滤器 bean 时,它可以正常工作:
WebAppSecurityConfiguration:(正常工作)
package com.espiritware.opusclick.restfullbackend.security;
@Configuration
public class WebAppSecurityConfiguration extends WebSecurityConfigurerAdapter
//@Autowired
//private LoginAuthenticationFilter opusClickLoginAuthenticationFilter;
//@Autowired
//private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception
//http.oauth2Client();
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterAt(LoginAuthenticationFilter(),
BasicAuthenticationFilter.class)
.addFilterAt(jwtAuthenticationFilter(),
BasicAuthenticationFilter.class);
http.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
@Bean
public PasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
@Bean
public LoginAuthenticationFilter LoginAuthenticationFilter()
return new LoginAuthenticationFilter();
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter()
return new JwtAuthenticationFilter();
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
我的问题是,当我在 FilterConfigurations
中执行 相同的配置 时,为什么会停止工作。我不知道是不是因为这个类在另一个包中找到。谁能解释这种奇怪行为的原因?
非常感谢!
【问题讨论】:
我认为LoginAuthenticationFilter
和JwtAuthenticationFilter
类也需要用@Configuration
注解。请检查这是否有效。
这两个过滤器都是不必要的,因为 spring security 已经支持基本登录(base64 enc 标头)并且已经在 spring security 5 @987654321 中实现了一个 JWTFilter @我不明白使用框架的意义如果你打算构建已经在框架中的东西?
【参考方案1】:
要消除此问题,您必须在 WebSecurity 类之外创建一个 bean,因为我注意到 @autowired 和 @bean 有时会被容器搞砸,原因是他无法在运行时识别对象。
@Component
public class PasswordEncoderConfiguration
@Bean
BCryptPasswordEncoder passwordEncoder()
return new BCryptPasswordEncoder();
您必须使用下面的方法将其自动连接到 Websecurityconfig 类,
@Autowired
private BCryptPasswordEncoder passwordEncoder;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception
// configure AuthenticationManager so that it knows from where to load
// user for matching credentials
// Use BCryptPasswordEncoder
auth.userDetailsService(jwtUserDetailsService).passwordEncoder(passwordEncoder);
【讨论】:
【参考方案2】:问题肯定与两个注释有关:@Autowired
用于过滤器,@Bean
注释用于authenticationManagerBean
方法。首先需要了解WebAppSecurityConfiguration
类将在两个过滤器都被自动装配时准备好使用,但是为了成功自动装配两个过滤器与AuthenticationManager
有关系,并且对于那个目标,我们通过@Bean
注释标记了方法authenticationManagerBean
,并且 Spring 尝试通过以下方式创建 AuthenticationManager
:
public AuthenticationManager authenticationManagerBean() throws Exception
return new AuthenticationManagerDelegator(this.authenticationBuilder, this.context);
正如您在创建AuthenticationManagerDelegator
时看到的那样,我们应该已经初始化了两个字段authenticationBuilder
和context
,但是我们刚刚开始创建我们的WebAppSecurityConfiguration
配置bean,它将被标记为创建时,直到所有字段都被初始化,它是专门为避免使用未初始化的字段和获得NullPointerException
异常而设计的。
但是如果查看 bean 定义的第二个选项,bean 创建的工作流程发生了如下变化:
WebAppSecurityConfiguration
没有用于自动装配的字段,我们可以轻松地首先创建配置 bean 并取消标记,如 in creation
在创建配置bean之后,所有@Bean
注解都将被处理并且在创建authenticationManagerBean
时我们不会得到异常,因为在我们创建WebAppSecurityConfiguration
配置时所有的字段都被初始化了,现在我们可以使用所有的父安全的方法。
附:从我的角度来看,通过以下方式定义 bean:
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return super.authenticationManagerBean();
这不是一个好主意,因为WebSecurityConfigurerAdapter
类将按正确的顺序创建所有必需的组件(bean),并且父类中的这些方法已打开以通过以下方式自定义实现 bean:
@Override
public AuthenticationManager authenticationManagerBean() throws Exception
return new CustomAuthenticationManager(...);
【讨论】:
这是完美的解释。理想情况下,我们不应该在 Configuration 类中使用 Autowired,因为 Configuration 类用于 bean 定义和布线,所以很明显,当 spring 执行 bean 布线时,它不能注入 Autowired 对象,这些对象可能具有尚未初始化的依赖对象,并且它给出了 InCreationException。 【参考方案3】:@Configuration 是给 Bean 配置的,不能用 @Autowired 自动注入普通的 bean,好像只支持这两种注入 1)@Value("$bean.name") String beanName; 2)@Inject 环境环境;环境是春天的特殊豆
WebAppSecurityConfiguration 更像是一个@Component Bean,而不是@Configuration Bean,你可以将@Component 和@Autowired 一起使用来注入过滤器Bean。
@Configuration 仅用于 Bean 配置,如果 DemoService 有 @Service 注解,则可以在 @Configuration 类中以这种方式注入它
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter(DemoService demoService)
return new JwtAuthenticationFilter(demoService);
【讨论】:
是的。我可以使用“@Autowired”在我的带注释的“@configuration”类中自动注入公共bean,这个工作正常。例如,如果我想在同一个类中使用“@Autowired”配置身份验证提供程序。例如,这对我有用:@Configuration public class WebAppSecurityConfiguration extends WebSecurityConfigurerAdapter @Autowired private JwtAuthenticationProvider jwtAuthenticationProvider; @Override protected void configure(AuthenticationManagerBuilder auth) auth.authenticationProvider(jwtAuthenticationProvider);
以上是关于Spring Boot UnsatisfiedDependencyException 创建名称为无法解析的循环引用的 bean 时出错的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spring Boot 应用程序 pom 同时需要 spring-boot-starter-parent 和 spring-boot-starter-web?
《02.Spring Boot连载:Spring Boot实战.Spring Boot核心原理剖析》