Using Guice 3 with JAX-WS in Java 6 outside web container

后端 未结 2 1478
生来不讨喜
生来不讨喜 2021-02-10 03:12

We have a situation where we use JSR-330 based injections to configure our stand-alone Java 6 applications, which works very well for getting configuration parameters across all

相关标签:
2条回答
  • 2021-02-10 03:40

    I'm not sure that I've understood every bit of the question. It looks to too easy for +500 bounty. Please post some code if that's not what you're searching for.

    Anyway, a simple solution which creates a web service with dependency injection:

    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);
    

    Below a more sophisticated solution with classpath scanning (Reflections) based on Marcus Eriksson's code from JAX-WS Guice integration. It publishes all classes which is annotated with @GuiceManaged as a webservice with 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);
    }
    

    The GuiceManaged annotation:

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

    And the HelloServiceImpl snippet:

    @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);
        }
    }
    
    0 讨论(0)
  • 2021-02-10 03:56

    you need to use the AbstractMultiInstanceResolver extension point.

    create the annotation GuiceManaged;

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

    implement the GuiceManagedFeature which is WebServiceFeature :

    public class GuiceManagedFeature extends WebServiceFeature {
        public static final String ID="FEATURE_GuiceManaged";
    
        @FeatureConstructor
        public GuiceManagedFeature()
        {
            this.enabled=true;
        }
    
        public String getID() {
            return ID;
        }
    }
    

    Implement InstanceResolver by Extending 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;
        }
    }
    

    Now Annotate your Service with @GuiceManaged & use @Inject for method level DI on your business method.

    0 讨论(0)
提交回复
热议问题