[英]Cyclic dependency in Spring Boot
將 org.springframework.boot 從 2.5.6 版本升級到 2.6.2 版本后,應用程序啟動時出現以下錯誤:
***************************
APPLICATION FAILED TO START
***************************
Description:
The dependencies of some of the beans in the application context form a cycle:
┌─────┐
| securityConfiguration
↑ ↓
| org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration
└─────┘
我從其他問題中知道,簡單的解決方法是使用選項allow-cirular-references ,但我想真正解決問題而不是使用解決方法。
這是我的安全配置 class:
package com.mycompany.myapp.servicex.configuration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${application.myapp.in-browser-allowed-origins}")
private String[] inBrowserAllowedOrigins;
private final String[] inBrowserAllowedMethods = new String[]{"POST", "OPTIONS"};
@Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.logout().disable();
}
@Bean
public WebMvcConfigurer corsConfigurer()
{
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/in-browser/login")
.allowedOrigins(inBrowserAllowedOrigins)
.allowedMethods(inBrowserAllowedMethods);
registry.addMapping("/**").allowedOrigins();
}
};
}
}
有人知道如何以編程方式打破循環依賴嗎?
我已經在corsConfigurer bean 和inBrowserAllowedOrigins屬性中使用 @Lazy 注釋,但沒有成功。
不要為WebMvcConfigurer
使用內部 bean,而是將其設置為正確的 class ,您可以使用@Configuration
對其進行注釋。
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Value("${application.myapp.in-browser-allowed-origins}")
private String[] inBrowserAllowedOrigins;
private final String[] inBrowserAllowedMethods = new String[]{"POST", "OPTIONS"};
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/in-browser/login")
.allowedOrigins(inBrowserAllowedOrigins)
.allowedMethods(inBrowserAllowedMethods);
registry.addMapping("/**").allowedOrigins();
}
}
現在您可以從您的安全配置中刪除corsConfiguration()
@Bean
方法,循環依賴就消失了。
或者另一種選擇是使用 Spring Security 來配置 CORS 而不是 Spring MVC。 這在Spring 安全參考指南中進行了解釋。
為此,您需要修改安全配置
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Value("${application.myapp.in-browser-allowed-origins}")
private String[] inBrowserAllowedOrigins;
private final String[] inBrowserAllowedMethods = new String[]{"POST", "OPTIONS"};
@Override
protected void configure(final HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
.logout().disable()
.cors(withDefaults());
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration conf = new CorsConfiguration();
conf.setAllowedOrigins(Arrays.asList(inBrowserAllowedOrigins));
conf.setAllowedMethods(Arrays.asList(inBrowserAllowedMethods));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/in-browser/login", configuration);
source.registerCorsConfiguration("/**", new CorsConfiguration());
return source;
}
}
這樣的事情也應該有效,因為現在 Spring 安全性已完全控制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.