Назад к вопросам
Middle+
121
questionbank

Есть ли возможность создать два Singleton'а в Spring?

Sobes Copilot

Получайте ответы в реальном времени

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

sobes.tech AI

Да, можно:

  1. Разные контексты: Каждый контекст Spring (например, два AnnotationConfigApplicationContext) будет управлять своим набором бинов, включая синглтоны. В каждом контексте будет свой экземпляр синглтона.

    // Singleton бин
    public class MySingleton {
        private static int counter = 0;
        private int instanceId;
    
        public MySingleton() {
            instanceId = ++counter;
        }
    
        public int getInstanceId() {
            return instanceId;
        }
    }
    
    // Конфигурация бина
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class AppConfig {
        @Bean
        public MySingleton mySingleton() {
            return new MySingleton();
        }
    }
    
    // Использование разных контекстов
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class Main {
        public static void main(String[] args) {
            ApplicationContext context1 = new AnnotationConfigApplicationContext(AppConfig.class);
            MySingleton singleton1 = context1.getBean(MySingleton.class);
            System.out.println("Singleton 1 from context 1, ID: " + singleton1.getInstanceId()); // Вывод: 1
    
            ApplicationContext context2 = new AnnotationConfigApplicationContext(AppConfig.class);
            MySingleton singleton2 = context2.getBean(MySingleton.class);
            System.out.println("Singleton 2 from context 2, ID: " + singleton2.getInstanceId()); // Вывод: 2
        }
    }
    
  2. Разные бин IDs (если бин определен несколько раз): Если один и тот же класс зарегистрирован в одном контексте под разными бин ID, Spring по умолчанию создаст отдельный синглтон для каждого ID. Это не совсем "два Singleton'а этого класса", а скорее два разных бина, каждый из которых имеет область видимости Singleton и использует один и тот же класс реализации.

    // Конфигурация с разными ID для одного класса
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class DifferentIdConfig {
        @Bean(name = "singletonA")
        public MySingleton mySingletonA() {
            return new MySingleton();
        }
    
        @Bean(name = "singletonB")
        public MySingleton mySingletonB() {
            return new MySingleton();
        }
    }
    
    // Использование бинов с разными ID
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class MainDifferentId {
        public static void main(String[] args) {
            ApplicationContext context = new AnnotationConfigApplicationContext(DifferentIdConfig.class);
            MySingleton singletonA = context.getBean("singletonA", MySingleton.class);
            MySingleton singletonB = context.getBean("singletonB", MySingleton.class);
    
            System.out.println("Singleton A ID: " + singletonA.getInstanceId()); // Вывод: 1
            System.out.println("Singleton B ID: " + singletonB.getInstanceId()); // Вывод: 2
        }
    }
    

Несмотря на возможности, стандартное и наиболее частое использование Singleton в Spring подразумевает один экземпляр бина определенного класса в рамках одного ApplicationContext.