← Назад к вопросам

Где хранится Singleton бин?

2.0 Middle🔥 161 комментариев
#Spring Boot и Spring Data#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Где хранится Singleton бин в Spring?

Основной ответ

Singleton бины хранятся в Spring контейнере (ApplicationContext) в специальной кэш-структуре. В частности, для singleton scope используются две основные карты:

// DefaultSingletonBeanRegistry.java (часть Spring Framework)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
private final Map<String, ObjectFactory<?>> singletonFactories = 
    new LinkedHashMap<>();
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();

Детали хранения

1. Главная карта - singletonObjects

Это основное место, где хранятся полностью инициализированные singleton бины:

// Когда бин создан и инициализирован, он попадает сюда
singletonObjects.put(beanName, beanInstance);

2. singletonFactories - фабрики объектов

Вспомогательная карта для разрешения циклических зависимостей (circular dependencies):

// На ранних стадиях создания бина
singletonFactories.put(beanName, new ObjectFactory<Object>() {
    public Object getObject() throws BeansException {
        return getEarlyBeanReference(beanName, mbd, bean);
    }
});

3. earlySingletonObjects - ранние синглтоны

Кэш для частично инициализированных бинов (для circular dependencies):

// При обнаружении циклической зависимости
earlySingletonObjects.put(beanName, singletonFactory.getObject());

Жизненный цикл Singleton бина

@Configuration
public class AppConfig {
    @Bean
    public UserService userService() {
        return new UserService();  // Этот объект создаётся один раз
    }
}

// Когда ApplicationContext инициализируется:
// 1. Создаёт экземпляр UserService
// 2. Вызывает @PostConstruct методы
// 3. Сохраняет в singletonObjects с ключом "userService"
// 4. При каждом обращении - возвращает тот же объект

Как получить доступ к синглтонам

// Через ApplicationContext
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService service = context.getBean(UserService.class);

// Все последующие вызовы вернут ТОТ ЖЕ объект
UserService service2 = context.getBean(UserService.class);
assert service == service2;  // true - один и тот же экземпляр

Важные моменты

Thread Safety

Spring использует ConcurrentHashMap для thread-safe доступа:

// Потокобезопасно - несколько потоков могут одновременно получать бин
UserService s1 = context.getBean(UserService.class);
UserService s2 = context.getBean(UserService.class);

Другие scope бинов

// Prototype - новый объект каждый раз
@Bean
@Scope("prototype")
public UserService userService() { ... }

// Request - один объект на HTTP запрос
@Bean
@Scope("request")
public RequestData data() { ... }

// Session - один объект на сессию
@Bean
@Scope("session")
public SessionData data() { ... }

Внутренняя структура

// Просмотр всех синглтонов (для отладки)
if (context instanceof DefaultListableBeanFactory) {
    DefaultListableBeanFactory factory = 
        (DefaultListableBeanFactory) context;
    String[] singletonNames = factory.getSingletonNames();
    for (String name : singletonNames) {
        System.out.println(name);  // Имена всех singleton бинов
    }
}

Заключение

Singleton бины хранятся в памяти приложения в контейнере Spring (ApplicationContext) в виде ConcurrentHashMap для обеспечения потокобезопасности и быстрого доступа. Это позволяет Spring гарантировать, что один и тот же экземпляр бина используется во всём приложении, что повышает производительность и позволяет управлять состоянием объектов.

Где хранится Singleton бин? | PrepBro