Одноэлементный класс или компонент. Это должно быть вызвано из разных мест

#java #spring-boot #singleton

Вопрос:

У меня есть ситуация, когда мне нужно сохранить в памяти некоторые данные с помощью spring boot, и это будет обновлять их время от времени. Мне нужно сохранить его на карте, но я немного смущен, следует ли мне реализовать свой собственный синглтон и использовать аннотации компонентов.

Я знаю, что для компонента аннотации по умолчанию объект будет использовать одноэлементный, но в этом случае я должен использовать 3 разных класса A, B и C. Мой вопрос здесь в том, создаст ли он компонент репозитория для класса A, другой для B и еще один для C, и каждый из них будет одноэлементным? Или он создаст только один для A, а затем, когда B захочет создать, он увидит, что один уже создан, и будет использовать тот же самый для C.

В противном случае я чувствую, что мне нужна моя собственная одноэлементная реализация

 Class Repository {
    Map<String, Config> db = new hashMap<>;
    ... singleton implementation

    public String getConfig(string key) { 
    return db.get(key);
   }
}

@Component
Class RepositoryComponent {
    Map<String, Config> db = new hashMap<>;

    public String getConfig(string key) { 
       return db.get(key);
    }
}

@Component
Class A { 
    @Autowire
    RepositoryComponent c;

    public someMethod() {
       Repository.getInstance().getConfig("key");
       c.getConfig("key");
    }
}

@Component
Class B { 
   @Autowire
   RepositoryComponent c;

   public someMethod() { 
      Repository.getInstance().getConfig("key");
      c.getConfig("key");
   }
}

@Component
Class C { 
    @Autowire
    RepositoryComponent c;
    
    public someMethod() { 
       Repository.getInstance().getConfig("key");
       c.getConfig("key");
    }
}
 

Ответ №1:

Если вы аннотировали класс с помощью @Component, в том же ApplicationContext будет только один компонент этого типа. Это поведение по умолчанию.

Если вы аннотировали класс с помощью @Component и @Scope(«прототип»), Spring будет создавать новый экземпляр каждый раз, когда он запрашивается.

Ответ №2:

RepositoryComponent С момента использования будет создан только один компонент @Component , что означает, что его область действия является одноэлементной. Как следствие, тот, который будет введен в классы A, B и C, будет точно таким же (все запросы на это имя компонента будут возвращать один и тот же объект, который кэшируется). Кроме того, любые изменения в RepositoryComponent компоненте будут отражены во всех ссылках на компонент.