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

Scala开发Spring Boot:Configuration类注入ConfigurationProperties异常排查

这个问题我之前也踩过坑,核心原因是Spring对@Configuration类的特殊代理机制,和Scala的构造函数编译逻辑撞在了一起,我来给你拆解清楚原因,再给几个可行的解决方案:

为什么会出现这些问题?

1. 构造注入报错NoSuchMethodException

Spring默认会给@Configuration类生成CGLIB动态代理,用来拦截@Bean方法调用,确保bean的单例特性。这个代理类需要调用父类(也就是你的Config类)的无参构造函数来实例化,但你的Config类只有带@Autowired参数的构造函数——Scala编译这类类时,默认不会生成无参构造,所以代理类找不到对应的构造方法,直接抛出异常。

2. 字段注入后properties为null

同样是CGLIB代理的锅:代理类的字段注入时机,晚于你可能使用这个字段的时机(比如在@Bean方法里直接引用properties)。当Spring调用配置类的@Bean方法时,代理类还没完成对原始类字段的注入,所以你拿到的就是null。

而@Service类的构造注入能正常工作,是因为Spring对服务类的代理逻辑不同:哪怕用CGLIB代理,服务类的代理会直接通过带参数的构造函数传递依赖,不需要依赖无参构造。


解决方案

方案1:关闭@Configuration的代理(最推荐)

从Spring Boot 2.2+开始,官方推荐关闭配置类的代理(当你的@Bean方法之间没有互相调用时),这样Spring就不会生成CGLIB代理,直接用原始类实例,构造注入就能正常工作:

@Configuration(proxyBeanMethods = false)
class Config @Autowired()(var properties: MessagePathProperties) {
  // 在这里可以正常使用properties
  @Bean
  def messageService(): MessageService = new MessageService(properties)
}

这个方式不仅解决了注入问题,还能提升应用启动性能。

方案2:给Config类添加无参构造函数

如果你的配置类必须保留代理(比如@Bean方法之间有依赖调用),可以通过Scala的辅助构造函数实现无参构造:

@Configuration
class Config {
  private var properties: MessagePathProperties = _

  // 带参数的构造函数用于Spring注入
  @Autowired
  def this(properties: MessagePathProperties) {
    this() // 调用无参辅助构造
    this.properties = properties
  }

  // 现在可以正常使用properties了
}

这样CGLIB代理类能正常实例化,Spring也会调用带参数的构造函数完成注入。

方案3:在@Bean方法中直接注入依赖

更简洁的方式是,不在Config类中保存properties字段,而是直接在@Bean方法的参数里注入:

@Configuration
class Config {
  @Bean
  def messageService(properties: MessagePathProperties): MessageService = {
    new MessageService(properties)
  }
}

Spring会自动解析@Bean方法的参数,注入对应的bean,完全绕开配置类的注入问题。


额外注意事项

  • 确保你的MessagePathProperties类正确标注了@ConfigurationProperties(prefix = "你的配置前缀"),你的应用类已经加了@EnableConfigurationProperties,这部分你已经做对了。
  • 不要把@Configuration类定义为Scala的case class——case class默认是final的,CGLIB无法生成代理类,会导致配置类失效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:43:30