... se l'istanza deve essere costruita manualmente, forse da una classe di fabbrica di terze parti? In precedenza, (Jersey 1.x), si potrebbe fare qualcosa di simile:Utilizzo di Jersey 2.0, come si registra un'istanza associabile per richiesta?
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;
}
};
}
}
La classe locale anonimo è in grado di accedere a un'istanza di restituire entro un certo margine. Ciò è utile quando non lavori con classi che hanno costruttori predefiniti, ma devono essere costruiti su base di richiesta.
Jersey 2.0 passato a HK2 come framework di iniezione delle dipendenze, ma ahimè, la pagina di migrazione (https://jersey.java.net/documentation/latest/migration.html) non fornisce un esempio di questo tipo di associazione e la documentazione HK2 non fornisce esempi utilizzando un AbstractBinder.
Per elaborare solo un po 'di più, sto cercando di fornire istanze di JPA EntityManager locali, indipendenti dal contenitore e risorse alle mie risorse. Questi devono essere prelevati da una classe di fabbrica singleton e dovrebbero limitarsi a una sola "unità di lavoro", che è una richiesta nel mio caso. Sono consapevole che ci sono soluzioni alternative (Basta iniettare la fabbrica, o associare a un threadlocal), ma ho trovato la soluzione precedente elegante e vorrei ricrearla se possibile.
EDIT:
Dopo aver scavato attraverso le javadocs HK2 per un po ', ho scoperto che qualcosa di simile può essere raggiunto come segue:
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) {}
}
E per registrarlo ...
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(new MyInjectableProvider());
}
}
Questo "sembra funzionare", ma sembra anche un po 'poco chiaro. dispose() non viene mai chiamato, ad esempio. Inoltre, questa associazione sembra comportarsi implicitamente come RequestScoped. La modifica della configurazione su bindFactory(this).to(MyInjectable.class).in(RequestScoped.class);
non sembra in realtà modificare il comportamento. Mi manca qualcosa o è questa la soluzione prevista?
Sto affrontando gli stessi identici problemi. Il tuo "EDIT" è stato molto utile. Grazie. Prima di leggere l'ultimo paragrafo del tuo post, anch'io ho scoperto che 'dispose' non viene mai chiamato dopo una richiesta. Sei riuscito a capire perché? – aioobe
Ciao, quale framework DI stai usando per il tuo progetto? Perché posso fornirti un paio di esempi di come stiamo facendo le cose con guizzo e abbiamo anche fatto con la saldatura. Con guice, usa guice-persist, dove EntityManager è scope of Request. Con Weld abbiamo creato un provider di ambito di richiesta. Inseriamo i nostri repository nelle risorse JAX. Ogni repository, EM iniettato, per la risoluzione delle operazioni del database. –
L'ambito predefinito è l'ambito della richiesta. Ovviamente, dichiararlo esplicitamente non lo cambia. Ad esempio, puoi dichiararlo singleton con "Singleton.class" o cosa non ti piace con questa soluzione? –