2011-10-07 12 views
5

Abbiamo una situazione in cui utilizziamo le iniezioni basate su JSR-330 per configurare le nostre applicazioni Java 6 standalone, che funziona molto bene per ottenere i parametri di configurazione su tutti i livelli .Uso di Guice 3 con JAX-WS in Java 6 all'esterno del contenitore Web

Abbiamo anche utilizzato i servizi web JAX-WS per un po 'utilizzando la prima distribuzione Metro stand-alone con Java 5 all'interno di un contenitore Web, ma con Java 6 usiamo solo la classe Endpoint per ottenere un ingombro minore.

Così ora ho una situazione in cui ho

  • Uno stand-alone Java 6 applicazione - senza servlet container (Jetty, Tomcat)
  • Un Guice 3 Injector impostare come piace a me.
  • Un Endpoint gestisce la mia classe annotata @javax.jws.WebService che espone i miei metodi come servizi Web.

Desidero che i metodi del servizio Web abbiano i loro campi @Inject gestiti in modo trasparente o per ottenere l'accesso all'iniettore. I può catturarlo come campo statico dal metodo principale, ma mi piacerebbe una soluzione più pulita.

Qualche suggerimento?

(Ho capito da JAX-WS and Guice 3 che il modulo http://jax-ws-commons.java.net/guice/ non funziona con Guice 3, e la soluzione suggerita è Tomcat specifico)

Sarebbero JSR-250 @Resource annotazioni essere utile qui?

+0

Si è scoperto che posso ottenere da per ora iniettando un fornitore nell'oggetto implementazione come faccio io Non ho bisogno di un'iniezione profondamente annidata. Bounty assegnato per rispondere facendomi capire questo. –

risposta

5

Non sono sicuro di aver capito ogni piccola domanda. Sembra troppo facile per +500 taglie. Si prega di inviare un po 'di codice se non è quello che stai cercando.

In ogni caso, una soluzione semplice, che crea un servizio web con l'iniezione di dipendenza:

final Module module = new HelloModule(); 
final Injector injector = Guice.createInjector(module); 
final HelloService helloService = injector.getInstance(HelloService.class); 

Endpoint.publish("http://localhost:8080/helloService", helloService); 

Qui di seguito una soluzione più sofisticata con la scansione classpath (Reflections) basata sul codice di Marcus Eriksson da JAX-WS Guice integration. Pubblica tutte le classi annotate con @GuiceManaged come servizio web con Endpoint.publish().

private void initGuicedWebservices(final String packageNamePrefix) 
     throws Exception { 
    final Reflections reflections = new Reflections(packageNamePrefix); 
    final Set<Class<?>> guiceManaged = 
     reflections.getTypesAnnotatedWith(GuiceManaged.class); 
    for (final Class<?> clazz : guiceManaged) { 
     doGuice(clazz); 
    } 
} 

private void doGuice(final Class<?> clazz) throws Exception { 
    final GuiceManaged guiceManagedAnnotation = 
     clazz.getAnnotation(GuiceManaged.class); 

    final Injector injector = createInjector(guiceManagedAnnotation); 

    final Object serviceObject = clazz.newInstance(); 
    injector.injectMembers(serviceObject); 

    final String address = guiceManagedAnnotation.address(); 

    Endpoint.publish(address, serviceObject); 
} 

private Injector createInjector(final GuiceManaged guiceManagedAnnotation) 
     throws Exception { 
    final Class<? extends Module>[] moduleClasses = 
     guiceManagedAnnotation.module(); 

    final List<Module> moduleInstances = new ArrayList<Module>(); 
    for (final Class<? extends Module> moduleClass : moduleClasses) { 
     moduleInstances.add(moduleClass.newInstance()); 
    } 

    return Guice.createInjector(moduleInstances); 
} 

Il GuiceManaged annotazione:

@Retention(RUNTIME) 
@Target(TYPE) 
@Documented 
public @interface GuiceManaged { 
    public Class<? extends Module>[] module(); 
    public String address(); 
} 

E il HelloServiceImpl frammento:

@GuiceManaged(module = HelloModule.class, 
    address = "http://localhost:8080/helloService") 
@WebService 
public class HelloServiceImpl implements HelloService { 

    @Inject // bound in HelloModule 
    public GreetingsService greetingsService; 

    @Override 
    @WebMethod 
    public String sayHello(final String name) { 
     return greetingsService.sayHello(name); 
    } 
} 
+1

Dopo aver riflettuto sulla tua risposta, mi sono reso conto che il meccanismo di Endpoint non fa nessuna novità, ma chiama il metodo annotato @WebMethod. Ciò significa che posso ottenere per ora solo avendo i fornitori iniettati nell'istanza. Come sempre, alcune domande sono difficili solo finché non sai come farlo. –

+1

Anche io uso frequentemente il bounty da 500 punti per attirare l'attenzione su una domanda. Se gli altri trovano la domanda semplice e la risposta banale, per me va bene. –

0

è necessario utilizzare il punto di estensione AbstractMultiInstanceResolver.

creare l'annotazione GuiceManaged;

@Retention(RUNTIME) 
@Target(TYPE) 
@Documented 
@WebServiceFeatureAnnotation(id=GuiceManagedFeature.ID, bean=GuiceManagedFeature.class) 
@InstanceResolverAnnotation(GuiceManagedInstanceResolver.class) 
public @interface GuiceManaged { 
} 

attuare la GuiceManagedFeature che è WebServiceFeature:

public class GuiceManagedFeature extends WebServiceFeature { 
    public static final String ID="FEATURE_GuiceManaged"; 

    @FeatureConstructor 
    public GuiceManagedFeature() 
    { 
     this.enabled=true; 
    } 

    public String getID() { 
     return ID; 
    } 
} 

Implementare InstanceResolver da estensione AbstractMultiInstanceResolver

public class GuiceManagedInstanceResolver extends AbstractMultiInstanceResolver { 
    private T instance=null; 
    public GuiceManagedInstanceResolver(@NotNull Class clazz) 
    { 
     super(clazz); 
    } 
    public T resolve(@NotNull Packet request) { 
     if(instance==null) 
     { 
      instance=create(); 
      Injector injector= Guice.createInjector(new WebServiceModule()); 
      injector.injectMembers(instance); 
     } 
     return instance; 
    } 
} 

Ora Annotate il vostro servizio con @GuiceManaged & uso @Inject per livello di metodo DI sul tuo metodo di business .

+0

Sei stato ispirato da http://developian.blogspot.com/2008/11/google-guice-and-jax-ws.html? –

+0

@ ThorbjørnRavnAndersen Sì, molto tempo fa, abbiamo avuto un problema simile al tuo e abbiamo cercato di usare quel blog come riferimento, poi abbiamo trovato Guice-Fruit con Guice 2.x. –

+0

Questo significa che ora usi Guice-Fruit e devi stare con Guice 2? –

Problemi correlati