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

Spring将Singleton Bean注入Prototype Bean导致Singleton重复创建

Why Your Singleton Bean Is Being Reinitialized When Injected into a Prototype Bean

First off, let's clarify a key point: injecting a singleton bean into a prototype bean is not inherently problematic in Spring. By default, Spring should inject the same singleton instance into every new prototype bean you create. The fact that your RangeFilteringParams (supposed singleton) is being reinitialized (with init filtering printing multiple times and changing IDs) means something is overriding this default behavior.

Let's walk through the most likely causes and fixes:

1. Verify Your Singleton's Scope Configuration

While @Component defaults to singleton scope, it's possible (though unlikely) that some other configuration is overriding this. Explicitly declare the scope to eliminate ambiguity:

@Component("rangeFilteringParams")
@Scope("singleton") // Explicitly enforce singleton scope
public class RangeFilteringParams {
    // Your existing fields, @PostConstruct, getters/setters, etc.
}

2. Check for Duplicate Bean Definitions

Spring will create multiple instances of a bean if there are multiple definitions for it. Look for these scenarios:

  • Did you define RangeFilteringParams both with @Component and in a @Configuration class using @Bean("rangeFilteringParams")? This would register two separate beans with the same name, leading to unexpected instances.
  • Is RangeFilteringParams being scanned by multiple @ComponentScan annotations? If your application has overlapping scan paths, the bean might be registered multiple times.

To debug this, you can print all bean definitions at startup to check for duplicates:

@Autowired
private ApplicationContext context;

// Somewhere in your startup logic
for (String beanName : context.getBeanDefinitionNames()) {
    if (beanName.equals("rangeFilteringParams")) {
        System.out.println("Found bean: " + beanName + ", type: " + context.getBean(beanName).getClass());
        System.out.println("Bean instance ID: " + System.identityHashCode(context.getBean(beanName)));
    }
}

3. Ensure You're Fetching the Prototype Bean Correctly

If you're manually instantiating FilteringWorkerPaired (e.g., new FilteringWorkerPaired()), Spring won't manage that instance, and the @Inject annotation won't work as expected. Instead, you must fetch the prototype bean from the Spring context every time you need a new instance:

@Autowired
private ApplicationContext context;

// When you need a new worker instance
FilteringWorkerPaired worker = context.getBean("filterWorkerPaired", FilteringWorkerPaired.class);

This ensures Spring properly injects the singleton RangeFilteringParams into each new prototype worker.

4. Rule Out Proxying Confusion

If your RangeFilteringParams is being proxied (e.g., for AOP), the instance ID you see might be the proxy's ID instead of the target singleton. However, the @PostConstruct method should still only run once for the actual singleton instance. If you're seeing init filtering printed multiple times, this confirms multiple actual instances are being created—so proxying isn't the root cause here.

Final Takeaway

Injecting a singleton into a prototype is a valid pattern. Your issue stems from unintended multiple instantiation of your "singleton" bean, not the injection pattern itself. Start with verifying the scope and checking for duplicate bean definitions, as those are the most common culprits.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:42:24