You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中@ConfigurationProperties对象返回null问题排查与解决

问题原因分析

这个问题我之前也踩过坑,核心原因是拦截器的初始化时机和Spring依赖注入的时机不匹配,导致Spring没法给你的HeaderInterceptor注入DomainProperties实例,具体拆解两点:

  1. 拦截器的加载优先级更高:Spring MVC在初始化DispatcherServlet阶段就会创建并注册拦截器,如果你的拦截器是手动new出来的(不是Spring容器管理的Bean),Spring根本不知道这个实例的存在,自然没法给它注入依赖,最终domainProperties就会是null。
  2. 你的HeaderInterceptor未被Spring托管:从代码看,你没有给拦截器添加@Component或其他Spring Bean注解,Spring不会把它纳入容器管理,也就无法触发自动注入逻辑。

解决方法

这里提供两种最常用的解决方案,你可以根据自己的场景选择:

方案一:把拦截器交给Spring容器管理(推荐)

这种方式让Spring全程托管拦截器的生命周期,自动处理依赖注入:

  1. 给HeaderInterceptor添加@Component注解,标记为Spring Bean:
@Component // 新增该注解
public class HeaderInterceptor extends HandlerInterceptorAdapter { 
    @Autowired 
    private DomainProperties domainProperties; 

    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        List<String> domainList= domainProperties.getDomainMap().values().stream().collect(Collectors.toList()); 
        domainList.stream().forEach(domain -> response.addHeader("Access-Control-Allow-Origin", domain)); 
        return super.preHandle(request, response, handler); 
    }
}
  1. 在WebMvc配置类中,通过@Autowired注入拦截器实例并注册:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private HeaderInterceptor headerInterceptor; // 从Spring容器获取实例

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(headerInterceptor)
                .addPathPatterns("/**"); // 根据你的业务需求配置拦截路径
    }
}

方案二:手动给拦截器注入依赖(适合不想托管拦截器的场景)

如果不想把拦截器交给Spring管理,可以在配置类中手动创建实例并传入依赖:

  1. 修改HeaderInterceptor,改用构造器注入(比Setter注入更安全,避免空指针):
public class HeaderInterceptor extends HandlerInterceptorAdapter { 
    private final DomainProperties domainProperties; 

    // 构造器注入依赖
    public HeaderInterceptor(DomainProperties domainProperties) {
        this.domainProperties = domainProperties;
    }

    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        List<String> domainList= domainProperties.getDomainMap().values().stream().collect(Collectors.toList()); 
        domainList.stream().forEach(domain -> response.addHeader("Access-Control-Allow-Origin", domain)); 
        return super.preHandle(request, response, handler); 
    }
}
  1. 在WebMvc配置类中手动创建拦截器并传入依赖:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private DomainProperties domainProperties;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 手动创建拦截器并传入依赖
        HeaderInterceptor headerInterceptor = new HeaderInterceptor(domainProperties);
        registry.addInterceptor(headerInterceptor)
                .addPathPatterns("/**");
    }
}

额外注意点

你的DomainProperties配置是没问题的:@Data @Component @ConfigurationProperties("app.cors")这个组合可以正确绑定application.properties中的配置到domainMap里,只要配置文件格式正确,就可以正常读取。

内容的提问来源于stack exchange,提问作者Bali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:58:38