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

Spring Boot 3中使用@Autoconfiguration创建带参数Prototype Bean的问题

Spring Boot 3 @AutoConfiguration下原型Bean创建问题解决方案

问题根源

@AutoConfiguration默认启用proxyBeanMethods = false,此时配置类不会被Spring代理。直接调用配置类中的prototypeComponent()方法时,只是普通Java方法调用,返回的是手动new的对象,不会经过Spring容器的Bean生命周期管理,也就无法生成受容器管控的原型Bean。而Spring Boot 2的@Configuration默认proxyBeanMethods = true,方法调用会被代理,每次调用都会生成新的原型Bean并交由容器管理。

解决方案(无需使用ApplicationContext.getBean)

方案1:显式开启配置类代理

直接给@AutoConfiguration设置proxyBeanMethods = true,恢复Spring Boot 2的代理行为,原代码逻辑可直接复用:

@AutoConfiguration(proxyBeanMethods = true)
public class TestPrototypeConfiguration {

    @Bean
    public SingletonComponent singletoneComponent() {
        return new SingletonComponent(this::prototypeComponent);
    }

    @Bean
    @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
    public PrototypeComponent prototypeComponent(int value) {
        return new PrototypeComponent(value);
    }
}

注意:此方式会关闭@AutoConfiguration默认的性能优化(避免代理类生成),若自动配置逻辑复杂,需权衡性能影响。

方案2:使用ObjectProvider传递参数获取原型Bean

利用Spring的ObjectProvider接口,通过getObject(Object... args)方法传递参数,获取受容器管理的原型Bean:

  1. 修改SingletonComponent,注入ObjectProvider<PrototypeComponent>:
@RequiredArgsConstructor
public class SingletonComponent {

    private final ObjectProvider<PrototypeComponent> prototypeProvider;

    public void test() {
        for (int i = 0; i < 5; i++) {
            // 每次调用都会生成新的、受容器管理的原型Bean
            PrototypeComponent component = prototypeProvider.getObject(i);
        }
    }
}
  1. 调整配置类,注入ObjectProvider并传递给SingletonComponent:
@AutoConfiguration
public class TestPrototypeConfiguration {

    @Bean
    public SingletonComponent singletoneComponent(ObjectProvider<PrototypeComponent> prototypeProvider) {
        return new SingletonComponent(prototypeProvider);
    }

    @Bean
    @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
    public PrototypeComponent prototypeComponent(int value) {
        return new PrototypeComponent(value);
    }
}

方案3:自定义Spring管理的工厂类

创建受Spring管控的工厂类,封装原型Bean的创建逻辑,避免直接暴露BeanFactory调用:

  1. 定义工厂类:
@Component
public class PrototypeComponentFactory {

    private final BeanFactory beanFactory;

    // 构造注入BeanFactory
    public PrototypeComponentFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public PrototypeComponent create(int value) {
        return beanFactory.getBean(PrototypeComponent.class, value);
    }
}
  1. 修改SingletonComponent依赖工厂类:
@RequiredArgsConstructor
public class SingletonComponent {

    private final PrototypeComponentFactory factory;

    public void test() {
        for (int i = 0; i < 5; i++) {
            PrototypeComponent component = factory.create(i);
        }
    }
}
  1. 配置类调整:
@AutoConfiguration
public class TestPrototypeConfiguration {

    @Bean
    public SingletonComponent singletoneComponent(PrototypeComponentFactory factory) {
        return new SingletonComponent(factory);
    }

    @Bean
    @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
    public PrototypeComponent prototypeComponent(int value) {
        return new PrototypeComponent(value);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 03:08:21