当前位置: 首页 > 知识库问答 >
问题:

Spring Boot 2.6回归:我如何修复适配器中的KeyClope循环依赖关系?

黄英韶
2023-03-14

Spring Boot 2.6. x似乎引入了一些更改,导致以前与Keycloak的集成具有循环引用,从而阻止应用程序启动;它在当前的2.5. x版本中正常工作和启动。

明确地说,除了

当然,预期的行为是应用程序启动正常,并像以前一样使用keyclope进行保护。

实际消息是:

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌──->──┐
|  keycloakSecurityConfig (field private org.keycloak.adapters.KeycloakConfigResolver org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter.keycloakConfigResolver)
└──<-──┘

全栈跟踪:

2021-11-30 12:49:07.308 DEBUG 7 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : Application failed to start due to an exception

org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'keycloakSecurityConfig': 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.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:656) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:639) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) ~[spring-beans-5.3.13.jar!/:5.3.13]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.getOrderedBeansOfType(ServletContextInitializerBeans.java:212) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:175) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAsRegistrationBean(ServletContextInitializerBeans.java:170) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.addAdaptableBeans(ServletContextInitializerBeans.java:155) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.ServletContextInitializerBeans.<init>(ServletContextInitializerBeans.java:87) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.getServletContextInitializerBeans(ServletWebServerApplicationContext.java:260) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.selfInitialize(ServletWebServerApplicationContext.java:234) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.embedded.tomcat.TomcatStarter.onStartup(TomcatStarter.java:53) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5219) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[?:?]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[?:?]
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) ~[?:?]
        at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) ~[tomcat-embed-core-9.0.55.jar!/:?]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:473) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:206) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.13.jar!/:5.3.13]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730) [spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412) [spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:302) [spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) [spring-boot-2.6.1.jar!/:2.6.1]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290) [spring-boot-2.6.1.jar!/:2.6.1]
        at REDACTED.SpringPortalApplication.main(SpringPortalApplication.java:17) [classes!/:2.0.0]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) [spring-portal.jar:2.0.0]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) [spring-portal.jar:2.0.0]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) [spring-portal.jar:2.0.0]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88) [spring-portal.jar:2.0.0]

2021-11-30 12:49:07.315 ERROR 7 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌──->──┐
|  keycloakSecurityConfig (field private org.keycloak.adapters.KeycloakConfigResolver org.keycloak.adapters.springsecurity.config.KeycloakWebSecurityConfigurerAdapter.keycloakConfigResolver)
└──<-──┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

该POM是广泛的,因为它包含了大量的Spring启动。。。(web、安全)条目,以及其他无趣的项目依赖项。我认为与这个特定问题相关的可能是与keyclope相关的东西:

  • org.keycloak.bom: keycloak-jamter-bom: 15.0.2(通过POM变量固定的版本)

并作为

  • 组织。springframework。启动:Spring启动安全

存在的唯一相关配置类是(为了简洁起见,删除了Javadoc):

@Configuration
@EnableWebSecurity
@ComponentScan(basePackageClasses = KeycloakSecurityComponents.class)
public class KeycloakSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) {
        KeycloakAuthenticationProvider kap = keycloakAuthenticationProvider();
        kap.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
        auth.authenticationProvider(kap);
    }

    @Bean
    public KeycloakSpringBootConfigResolver keycloakConfigResolver() {
        return new KeycloakSpringBootConfigResolver();
    }

    @Bean
    @Override
    protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        super.configure(http);
        http.authorizeRequests()
                .antMatchers("/**")
                .authenticated();
    }

}

我戳了一下Keycloak代码,似乎抽象的o. k. a. s. c. KeycloakWebSecurityConfigrerAdapter,我为上面的配置类扩展了它,它有一个@Autow的(必需=false)私有字段o. k. a. KeycloakConfigResolver-正是循环引用错误中提到的。

我尝试过:

>

  • 将带注释的@Bean提供程序方法(返回KeyCoverConfigResolver的实现,在上面的配置类中,它只是KeyCovereSpringBootConfigResolver)移动到另一个类;导致该类也在循环引用错误中被提及,作为类路径上的一项。

    只是删除返回KeycloakSpringBootConfigResolver的提供者方法,并查看是否有其他东西提供它;我意识到这没有意义,并且它按预期失败,因为这里使用的Keycloak资源没有任何变化(从15.0.2开始)-此外,如果字段为空,则获取配置的默认方法是o. k. a. s. c中的JSON文件。KeycloakWebSecurityConfigrerAdapter::adapterDeploymentContext。

    更多的阅读,现在我不再理解为什么我所做的实际工作——它有一个o.k.a.KeyCloveConfigResolver的构造函数注入实例,它必须使用的提供程序本身是一个非静态方法——这意味着必须构建一个实例。根据前面的要点,注释掉我提供了o.k.a.KeyCloveConfigResolver实现的方法会导致它默认为注入字段,这是尝试JSON文件的空条件。

    可能相关,但不确定;似乎不是:最近的问题在这里Spring boot keycloak循环参考

  • 共有1个答案

    湛玄裳
    2023-03-14

    允许循环依赖可能不是最好的选择。

    您可以做的一件事是为您的KeycloakConfigResolver bean创建一个特定的配置类。

    package com.stackoverflow;
    
    import org.keycloak.adapters.springboot.KeycloakSpringBootConfigResolver;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class KeycloakConfiguration {
    
        @Bean
        public KeycloakSpringBootConfigResolver KeycloakConfigResolver() {
            return new KeycloakSpringBootConfigResolver();
        }
    }
    
     类似资料:
    • 问题内容: 我最近一直在使用nodejs,并且仍然要处理模块系统,因此很抱歉这是一个明显的问题。我想要大致如下的代码: a.js (主文件与节点一起运行) b.js 我的问题似乎是我无法从ClassB实例中访问ClassA实例。 有没有正确/更好的方法来构造模块来实现我想要的?是否有更好的方式在模块之间共享变量? 问题答案: 尽管node.js确实允许循环依赖,但正如您所发现的那样,它可能很杂乱,

    • 我最近一直在使用nodejs,并且仍然在掌握模块系统,所以如果这是一个明显的问题,请原谅。我想要大致如下的代码: a.js(主文件与节点一起运行) b.js 我的问题似乎是我无法从ClassB的实例中访问ClassA的实例。 有没有正确/更好的方法来构建模块以实现我想要的?有没有更好的方法在模块之间共享变量?

    • 我是毕业生的新手,我需要配置我的构建.gradle文件。我正在使用硒网络驱动程序,我有.jar文件列表。我如何将此jar文件作为依赖项包含在我的build.gradle文件中?我有这个.jar在我的包中一个名为lib的文件夹中。我有 }但是我一直有下面的错误: 失败:生成失败,出现异常。 其中:构建文件“/主页/ola/工作区/构建分级”行: 20 出错了:评估根项目“工作区”时出现问题。无法将对

    • 创建一个Android项目“MyApp” 导入ActionBarSherlock(ABS)、DirectionalViewPager(DVP)或任何其他使用android支持库的开源库。 将库添加到项目“MyApp” 我知道我应该从libs文件夹中删除android-support-v4.jar,并且只保留一个副本。但是,这并没有解决我的问题。 当我试图从MyApp中删除android-suppo

    • 问题内容: 我正在将Java项目从Ant迁移到Gradle。我认为最好的解决方案是使用Gradle的多项目支持,但是我找不到摆脱循环依赖的方法。 原始项目已设置为具有以下布局: 之间的关系,并且,是棘手的。将取决于或根据配置文件。同样,无论配置属性如何,都依赖和。并且永远不会在同一时间建造。 我认为一种快速的解决方案是在: 接下来,我想过要找到一种方法来使之更接近公正工作。这导致我想到了这一点:

    • 问题内容: 我有两个文件和,分别定义了两个类和。 直到今天,用于引用该对象的定义,因此我已经做了 在文件中。 但是,到目前为止,我已经为引用该对象的对象创建了一个新方法。 尝试导入时遇到了问题:我尝试了一下,当程序运行并调用了using的方法时,出现了一个未定义的异常。 我该怎么办? 问题答案: 导入Python模块 是一篇很棒的文章,介绍了Python中的循环导入。 解决此问题的最简单方法是将路