简体   繁体   English

Spring Boot UnsatisfiedDependencyException 创建名称为不可解析循环引用的 bean 时出错

[英]Spring Boot UnsatisfiedDependencyException Error creating bean with name unresolvable circular reference

I'm developing an application with Spring Secuity where I have some custom filters, but I have problems configuring them correctly.我正在使用 Spring Secuity 开发一个应用程序,其中有一些自定义过滤器,但在正确配置它们时遇到了问题。 Consider the following custom filters:考虑以下自定义过滤器:

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: 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;
        }
    }

}

FilterConfigurations:过滤器配置:

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: (Fails) 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();
    }

}

When I run the application it throws me the following exception:当我运行应用程序时,它会抛出以下异常:

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

However, when I comment on my entire FilterConfigurations class and I do the configuration of my filters beans directly in my WebAppSecurityConfiguration that works without problems:但是,当我评论我的整个FilterConfigurations类并直接在我的WebAppSecurityConfiguration中配置我的过滤器 bean 时,它可以正常工作:

WebAppSecurityConfiguration: (Works Without Problems) 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();
    }

}

My Question is for what reason when I do the same configuration in my FilterConfigurations this stops working.我的问题是当我在我的FilterConfigurations进行相同的配置时,这是出于什么原因而停止工作。 I don't know if it is because this class found in another package.不知道是不是因为这个类是在另一个包中找到的。 Someone who can explain the reason for this strange behavior?谁能解释这种奇怪行为的原因?

Many Thanks!非常感谢!

Definitely issue is related with two annotations: @Autowired for filters and @Bean annotation for authenticationManagerBean method.绝对问题与两个注释有关:用于过滤器的@Autowired和用于authenticationManagerBean方法的@Bean注释。 First of all need to understand that WebAppSecurityConfiguration class will be ready for use when both filters were autowired, but for successful autowiring both filters have relation on AuthenticationManager , and for that target we marked method authenticationManagerBean by @Bean annotation, and Spring tried to create AuthenticationManager in following way:首先需要了解WebAppSecurityConfiguration类在两个过滤器都自动装配时就可以使用了,但是为了成功自动装配这两个过滤器都在AuthenticationManager上有关系,并且对于那个目标,我们通过@Bean注释标记了方法authenticationManagerBean ,并且 Spring 尝试创建AuthenticationManager通过以下方式:

public AuthenticationManager authenticationManagerBean() throws Exception {
    return new AuthenticationManagerDelegator(this.authenticationBuilder, this.context);
}

as you can see for creating AuthenticationManagerDelegator we should have initialized two fields authenticationBuilder and context , but we have just started creating our WebAppSecurityConfiguration configuration bean, which will be marked as on creation until all fields are initialized, it was made specifically for avoiding of using uninitialized fields and getting NullPointerException exceptions.正如您在创建AuthenticationManagerDelegator所看到的,我们应该初始化两个字段authenticationBuildercontext ,但是我们刚刚开始创建我们的WebAppSecurityConfiguration配置 bean,它将在创建时标记为直到所有字段都初始化,它是专门为避免使用未初始化的字段和获取NullPointerException异常。 But if review the second option of beans defitions, the workflow of beans creation was changed in following way:但是如果查看 beans defitions 的第二个选项,bean 创建的工作流程发生了以下变化:

  1. WebAppSecurityConfiguration doesn't have fields for autowiring and we can easily create first of all configuration bean and unmark like in creation WebAppSecurityConfiguration没有用于自动装配的字段,我们可以轻松地首先创建所有配置 bean 并像in creation一样取消标记
  2. after config bean was created, all @Bean annotations will be processed and on creating authenticationManagerBean we will not get the exception, because all fields were initialized when we was creating WebAppSecurityConfiguration configuration and now we can use all parent methods safely.创建配置 bean 后,所有@Bean注释将被处理,并且在创建authenticationManagerBean我们不会得到异常,因为所有字段在我们创建WebAppSecurityConfiguration配置时都已初始化,现在我们可以安全地使用所有父方法。

PS From my point of view, defining beans in following way: PS从我的角度来看,以以下方式定义bean:

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

is not good idea, because WebSecurityConfigurerAdapter class will create all required components(beans) in correct order, and these methods from parent class were opened for customization implementation of bean in following way:不是个好主意,因为WebSecurityConfigurerAdapter类会按照正确的顺序创建所有需要的组件(bean),并且父类中的这些方法被打开用于 bean 的自定义实现,如下所示:

@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return new CustomAuthenticationManager(...);
}

To eliminate this issue you have to create a bean outside of the WebSecurity class since I noticed @autowired and @bean mess up sometimes by container, the reason is he can't identify the objects at the run time.为了消除这个问题,你必须在 WebSecurity 类之外创建一个 bean,因为我注意到 @autowired 和 @bean 有时会被容器弄乱,原因是他无法在运行时识别对象。

    @Component
public class PasswordEncoderConfiguration {

    @Bean
    BCryptPasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }
}

and you have to Autowired this to Websecurityconfig class by using below,并且您必须使用下面的方法将其自动连接到 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);
}

@Configuration is for Bean config, you can't use @Autowired to auto inject common beans, It seems that it only supports these two kind of inject 1)@Value("${bean.name}") String beanName; @Configuration 是为Bean 配置的,不能用@Autowired 来自动注入普通bean,好像只支持这两种注入 1)@Value("${bean.name}") String beanName;
2)@Inject Environment env; 2)@Inject环境env; Environment is a special bean in spring环境是春天的特殊豆

WebAppSecurityConfiguration is more like a @Component Bean, not a @Configuration Bean, you can use @Component and @Autowired together to inject filter Beans. WebAppSecurityConfiguration 更像是一个@Component Bean,而不是@Configuration Bean,你可以将@Component 和@Autowired 一起使用来注入过滤器Bean。

@Configuration is just for Bean config, if DemoService has a @Service annotion, you can inject it this way in @Configuration class @Configuration 仅用于Bean 配置,如果DemoService 有@Service 注解,则可以在@Configuration 类中以这种方式注入

@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter(DemoService demoService) {
    return new JwtAuthenticationFilter(demoService);
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Boot + Quartz:“请求的 bean 正在创建中:是否存在无法解析的循环引用?” - Spring Boot + Quartz: "Requested bean is currently in creation: Is there an unresolvable circular reference?" UnsatisfiedDependencyException:请求的 bean 当前正在创建无法解析的循环引用 - UnsatisfiedDependencyException: Requested bean is currently in creation unresolvable circular reference spring - 启动(创建 bean 时出错) - org.springframework.beans.factory.UnsatisfiedDependencyException:使用名称创建 bean 时出错 - spring - boot (error while creating beans ) - org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 在TomEE上部署Spring Boot应用程序时出错:UnsatisfiedDependencyException:创建名称为&#39;employeeController&#39;的bean时出错 - Error deploying Spring Boot app on TomEE: UnsatisfiedDependencyException: Error creating bean with name 'employeeController' UnsatisfiedDependencyException - 创建具有名称的 bean 时出错 - UnsatisfiedDependencyException - Error creating bean with name UnsatisfiedDependencyException:使用名称创建 bean 时出错 - UnsatisfiedDependencyException: Error creating bean with name 当我尝试使用Spring Boot为SessionFactory创建Bean时无法解析的循环引用 - Unresolvable circular reference when I try to create the bean for SessionFactory with Spring Boot 弹簧无法解析的圆形参考 - Spring unresolvable circular reference 创建多个 Bean 时出错:是否存在无法解析的循环引用? - Error for creating multiples Beans : Is there an unresolvable circular reference? SPRING:所请求的Bean当前正在创建中:是否存在不可解析的循环引用 - SPRING: Requested bean is currently in creation: Is there an unresolvable circular reference
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM