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

为何registerSingleton()注册的Spring Bean不在getBeanDefinitionNames()中?是否为设计如此?

Why aren't Spring Beans registered via registerSingleton() visible in getBeanDefinitionNames()?

Great question — this boils down to how Spring internally manages bean metadata and instantiated objects. Let’s break this down clearly:

1. The core distinction: Bean Definitions vs. Instantiated Singletons

Spring keeps two separate stores for beans under the hood:

  • Bean Definitions: These are metadata blueprints that tell Spring how to create a bean (e.g., which class to use, constructor arguments, dependencies, scope). Methods like getBeanDefinitionNames() only return names of beans that have these metadata definitions — think beans from @Component classes, XML <bean> tags, or @Bean methods in configuration classes.
  • Singleton Cache: This is where fully built singleton objects live. When you use ConfigurableListableBeanFactory.registerSingleton(), you’re directly dropping a pre-instantiated object into this cache — no corresponding Bean Definition is created or stored.

Since getBeanDefinitionNames() only scans the Bean Definition store, beans registered via registerSingleton() won’t show up here.

2. Is this intentional design?

Absolutely. This is a deliberate choice in Spring’s BeanFactory architecture:

  • Bean Definitions exist for beans that Spring needs to manage end-to-end (instantiation, dependency injection, post-processing, lifecycle callbacks, etc.).
  • registerSingleton() is meant for cases where you already have a fully constructed object and just want Spring to manage it as a singleton — no need for a Bean Definition because Spring doesn’t have to build the object itself.

Alternative ways to get registered singletons

If you need to access beans registered via registerSingleton(), use these methods instead:

a. Use getSingletonNames() from ConfigurableListableBeanFactory

This method returns names of all singleton objects in the singleton cache, including those registered via registerSingleton():

@Autowired
private ConfigurableListableBeanFactory beanFactory;

public void listAllSingletons() {
    String[] allSingletonNames = beanFactory.getSingletonNames();
    for (String name : allSingletonNames) {
        System.out.println("Singleton bean name: " + name);
    }
}

b. Use getBeanNamesForType() or getBeansOfType() from ApplicationContext

If you know the bean’s type, you can retrieve all matching beans (including singleton registrations):

@Autowired
private ApplicationContext context;

public void findBeansByType() {
    // Get names of all beans matching MyBean type
    String[] beanNames = context.getBeanNamesForType(MyBean.class);
    
    // Get the actual bean objects mapped to their names
    Map<String, MyBean> beanMap = context.getBeansOfType(MyBean.class);
}

c. Use getBean() directly

If you know the exact name you used to register the singleton, you can fetch it directly with context.getBean("yourSingletonName") — this works regardless of whether the bean came from a Bean Definition or registerSingleton().


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:59:18