... если экземпляр необходимо создать вручную, возможно, сторонним фабричным классом? Ранее (Jersey 1.x), вы могли бы сделать что-то вроде этого:Использование Джерси 2.0, как вы регистрируете экземпляр привязки для запроса?
public class MyInjectableProvider extends PerRequestTypeInjectableProvider<Context, MyInjectable> {
public MyInjectableProvider() {
super(MyInjectable.class);
}
@Override
public Injectable<MyInjectable> getInjectable(ComponentContext ic, Context context) {
MyInjectable myInjectableInstance = //...
return new Injectable<MyInjectable>() {
@Override
public MyInjectable getValue() {
return myInjectableInstance;
}
};
}
}
анонимный локальный класс может получить доступ к экземпляру, чтобы вернуться в какой-то области. Это полезно, если вы не работаете с классами, у которых есть конструкторы по умолчанию, но они должны быть построены по запросу.
Джерси 2.0 переключился на HK2 как на платформу внедрения зависимостей, но, увы, страница миграции (https://jersey.java.net/documentation/latest/migration.html) не является примером такого типа привязки, а документация HK2 не содержит примеров с использованием AbstractBinder.
Чтобы разработать немного больше, я пытаюсь предоставить ресурсы-локальные, контейнер-агностические экземпляры JPA EntityManager для моих ресурсов. Они должны быть получены из одного заводского класса Singleton и должны придерживаться только одного «единицы работы», который является запросом в моем случае. Я знаю, что есть обходные пути (просто введите завод или привяжите к threadlocal), но я нашел предыдущее решение элегантным и хотел бы его воссоздать, если это возможно.
EDIT:
После рытья через ¯hk2 Javadocs для немного, я обнаружил, что нечто подобное может быть достигнуто следующим образом:
public class MyInjectableProvider extends AbstractBinder
implements Factory<MyInjectable> {
@Override
protected void configure() {
bindFactory(this).to(MyInjectable.class);
}
@Override
public MyInjectable provide() {
return getMyInjectable();
}
@Override
public void dispose(MyInjectable instance) {}
}
А зарегистрировать его ...
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(new MyInjectableProvider());
}
}
Это «кажется, работает», но это также кажется немного неясным. Например, dispose() никогда не вызывается. Кроме того, эта привязка, по-видимому, неявно ведет себя как RequestScoped. Изменение конфигурации на bindFactory(this).to(MyInjectable.class).in(RequestScoped.class);
, по-видимому, не влияет на поведение. Я что-то упустил, или это намеченное решение?
Я столкнулся с теми же проблемами. Ваш «EDIT» был очень полезен. Спасибо. Перед прочтением последнего абзаца вашего сообщения я также обнаружил, что 'dispose' никогда не вызывается после запроса. Вам удалось понять, почему? – aioobe
Здравствуйте, какой каркас DI вы используете для своего проекта? Потому что я могу предоставить вам пару примеров того, как мы делаем вещи с узором, а также мы сделали со сваркой. С помощью guice используйте guice-persist, где EntityManager является областью запроса. С Weld мы создали поставщика области запросов. Мы добавляем наши репозитории в ресурсы JAX. Каждый репозиторий вводит EM для разрешения операций с базой данных. –
Область по умолчанию - область запроса. Конечно, объявление этого явно не меняет этого. Вы можете, например, объявить его singleton с помощью «Singleton.class» или что вам не нравится с этим решением? –