Создание объектов с помощью AssistedInject Factory в Guice
У меня есть класс, который должен вводиться двумя разными способами:
для общего назначения как синглтон
настроенная версия как RequestScoped.
Пример:
public class TaskProcessorService implements TaskProcessor {
private final TaskRegistry taskRegistry;
@Inject
public TaskProcessorService(TaskRegistry taskRegistry){
this(taskRegistry, null);
}
@AssistedInject
public TaskProcessorService(TaskRegistry taskRegistry, @Assisted String userId) {...}
public synchronized void performTask(){...}
}
Допустим, каждый может использовать объект общего назначения и конкурировать за операцию executeTask (поскольку она синхронизирована), или они могут инвестировать и создавать свои собственные экземпляры / экземпляры.
Для общего назначения я создал интерфейс
public interface TaskProcessor{
void performTask();
}
и обязательный:
bind(TaskProcessor.class).to(TaskProcessorService .class).in(Singleton.class);
и для настроенной версии я создал фабрику
public interface TaskProcessorFactory{
public TaskProcessor(@Assisted String userId);
}
и установил его:
install(new FactoryModuleBuilder()
.implement(TaskProcessorService.class, TaskProcessorService.class)
.build(TaskProcessorFactory.class));
Я попробовал это, и это работало во время выполнения (я надеюсь, что я не делал ошибок при написании вышеупомянутых фрагментов кода вручную), однако я не уверен, работает ли он полностью так, как я хотел, так как я только написал и не имел времени полностью проверить это еще.
Но потом я понял, что не знаю, как работает завод. Для разных пользователей ('userId') он должен создавать разные экземпляры, но как насчет того же userId? Допустим, какой-то Джон Доу хочет создать 3 экземпляра TaskProcessorService. Будет ли фабрика создавать 3 разных экземпляра для каждого вызова (при условии, что параметр будет одинаковым - идентификатор Джона Доу)?
Это главный вопрос: всегда ли фабрика создает новые объекты даже для вызовов с одинаковыми параметрами? Не удалось найти никаких доказательств этого в документации, и я не уверен на 100%, не был ли создан какой-то механизм кэширования.
И второй вопрос, является ли это оптимальным решением проблемы?
1 ответ
Ответ на ваш первый вопрос - да. В вашем случае он всегда будет создавать разные объекты. По второму вопросу продолжайте чтение.
Неправильно иметь 2 привязки, относящиеся к одному и тому же интерфейсу. В случае объекта с двумя конструкторами, вы аннотируете их обоих @AssistedInject
и на фабрике вам нужно 2 метода, отражающие эти конструкторы. Затем просто установите его, используя FactoryModuleBuilder
,