You need to enable JavaScript to run this app. 如何注入Supplier类型的Bean?注入时出现Class has no fields错误如何解决
优惠活动
大模型
产品
解决方案
定价
更多

如何注入Supplier类型的Bean?注入时出现Class has no fields错误如何解决

问题原因

  1. Spring 对Supplier类型的特殊解析逻辑:Spring 4.3及以上版本默认支持Supplier作为依赖注入的包装类型,会自动解析Supplier<T>对应的T类型的Bean,而非直接注入Supplier实例本身,导致你注册的Supplier<Set<String>> Bean没有被正确匹配到注入点。
  2. Lambda实现的Supplier代理失败:你通过lambda表达式返回的Supplier是JDK动态生成的合成类,该类被final修饰且无公开构造方法,当配置类默认开启proxyBeanMethods = true时,Spring会尝试对@Bean返回的实例做CGLIB代理,lambda生成的类无法被代理,触发"Class has no fields"报错。

解决方法

  • 方法1:给Supplier Bean指定名称,注入时按名称匹配
    给配置类的Supplier Bean添加自定义Bean名:

    @Bean("stringSetSupplier")
    public Supplier<Set<String>> set() {
        return () -> Sets.newHashSet("100");
    }
    

    类A中注入时指定对应Bean名:

    @Inject
    @Named("stringSetSupplier")
    private Supplier<Set<String>> set;
    

    这种方式可以跳过Spring的Supplier自动解包逻辑,直接按名称匹配到你注册的Supplier实例。

  • 方法2:使用具名类实现Supplier,避免lambda代理问题
    定义一个静态类实现Supplier接口:

    public static class StringSetSupplier implements Supplier<Set<String>> {
        @Override
        public Set<String> get() {
            return Sets.newHashSet("100");
        }
    }
    

    配置类中返回该类的实例:

    @Bean
    public Supplier<Set<String>> set() {
        return new StringSetSupplier();
    }
    

    具名类可被Spring正常代理,不会触发合成类相关的报错。

  • 方法3:关闭配置类的Bean方法代理
    如果你不需要配置类的Bean方法代理能力,直接修改配置类注解关闭代理:

    @Configuration(proxyBeanMethods = false)
    @Import({someClass.class})
    public class UnitTestConfig {
        // 原有配置保持不变
    }
    

    关闭代理后Spring不会再尝试对@Bean返回的实例做CGLIB增强,规避lambda类无法代理的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 06:06:01