#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
компоненте будут отражены во всех ссылках на компонент.