2016-03-23 4 views
0

У меня есть следующие Jersey ресурс:Вводят EJB в Джерси класса ресурсов

@Path("service") 
public class Service implements IService { 

    @EJB 
    RESTWebserviceController restWebserviceController; 
... 

(где RESTWebserviceController является @Stateless EJB)

Как сообщили в других потоков на эту тему, я создал следующую реализацию интерфейс InjectableProvider.

@Provider 
public class EJBProvider implements InjectableProvider<EJB, Type> { 

    @Override 
    public ComponentScope getScope() { 
     return ComponentScope.Singleton; 
    } 

    @Override 
    public Injectable getInjectable(ComponentContext cc, EJB ejb, Type t) { 
     if (!(t instanceof Class)) { 
      return null; 
     } 

     try { 
      Class c = (Class) t; 
      Context ic = new InitialContext(); 

      final Object o = ic.lookup(c.getName()); 

      return new Injectable<Object>() { 
       public Object getValue() { 
        return o; 
       } 
      }; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

По-прежнему контейнер не может вводить RESTWebserviceController. Im работает Glassfish 3.1.2 с использованием Jersey 1.11.

The following errors and warnings have been detected with resource and/or provider classes: 
Missing dependency for field: schnittstelle.rest.controller.RESTWebserviceController schnittstelle.rest.Service.restTWebserviceController 

ответ

1

Вот решение. Создайте следующие два класса:

ApplicationBeans.java

import javax.enterprise.context.ApplicationScoped; 
import javax.enterprise.context.spi.CreationalContext; 
import javax.enterprise.inject.spi.Bean; 
import javax.enterprise.inject.spi.BeanManager; 
import javax.inject.Inject; 
import javax.naming.InitialContext; 
import javax.naming.NamingException; 

/** 
* Gives direct access to managed beans - Designed to be used from unmanaged code 
* 
* @author lgrignon 
* 
*/ 
@ApplicationScoped 
public class ApplicationBeans { 

    protected static ApplicationBeans instance; 
    @Inject 
    private BeanManager beanManager; 

    /** 
    * Gets instance 
    * 
    * @return Instance from managed environment 
    */ 
    public static ApplicationBeans instance() { 
     if (instance == null) { 
      BeanManager beanManager; 
      InitialContext ctx = null; 
      try { 
       ctx = new InitialContext(); 
       beanManager = (BeanManager) ctx.lookup("java:comp/BeanManager"); 
      } catch (NamingException e) { 
       try { 
        beanManager = (BeanManager) ctx.lookup("java:app/BeanManager"); 
       } catch (NamingException ne) { 
        throw new RuntimeException("Unable to obtain BeanManager.", ne); 
       } 
      } 

      instance = getBeanFromManager(beanManager, ApplicationBeans.class); 
     } 

     return instance; 
    } 

    /** 
    * Gets bean instance from context 
    * 
    * @param <T> 
    *   Bean's type 
    * @param beanType 
    *   Bean's type 
    * @param annotations 
    *   Bean's annotations 
    * @return Bean instance or null if no 
    */ 
    public static <T> T get(final Class<T> beanType, Annotation... annotations) { 
     return instance().getBean(beanType, annotations); 
    } 

    /** 
    * Gets bean instance from context 
    * 
    * @param <T> 
    *   Bean's type 
    * @param beanType 
    *   Bean's type 
    * @param annotations 
    *   Bean's annotations 
    * @return Bean instance or null if no 
    */ 
    public <T> T getBean(final Class<T> beanType, Annotation... annotations) { 
     return getBeanFromManager(beanManager, beanType, annotations); 
    } 

    @SuppressWarnings("unchecked") 
    private static <T> T getBeanFromManager(BeanManager beanManager, final Class<T> beanType, Annotation... annotations) { 
     Set<Bean<?>> beans = beanManager.getBeans(beanType, annotations); 
     if (beans.size() > 1) { 
      throw new RuntimeException("Many bean declarations found for type " + beanType.getSimpleName()); 
     } 

     if (beans.isEmpty()) { 
      throw new RuntimeException("No bean declaration found for type " + beanType.getSimpleName()); 
     } 

     final Bean<T> bean = (Bean<T>) beans.iterator().next(); 
     final CreationalContext<T> context = beanManager.createCreationalContext(bean); 
     return (T) beanManager.getReference(bean, beanType, context); 
    } 
} 

InjectionProvider.java

import javax.inject.Inject; 
import java.lang.reflect.Type; 
import javax.ws.rs.ext.Provider; 
import com.sun.jersey.core.spi.component.ComponentContext; 
import com.sun.jersey.core.spi.component.ComponentScope; 
import com.sun.jersey.spi.inject.Injectable; 
import com.sun.jersey.spi.inject.InjectableProvider; 

@Provider 
public class InjectionProvider implements InjectableProvider<Inject, Type> { 

    public ComponentScope getScope() { 
     // CDI will handle scopes for us 
     return ComponentScope.Singleton; 
    } 

    @Override 
    public Injectable<?> getInjectable(ComponentContext context, 
      Inject injectAnno, Type t) { 
     if (!(t instanceof Class)) { 
      throw new RuntimeException("not injecting a class type ?"); 
     } 

     Class<?> clazz = (Class<?>) t; 

     final Object instance = ApplicationBeans.get(clazz); 

     return new Injectable<Object>() { 
      public Object getValue() { 
       return instance; 
      } 
     }; 
    } 
} 

Затем сделать класс, который должен быть введен @RequestScoped и ввести его через @Inject , Если вы не уже есть beans.xml файл, создайте в папке WEB-INF (для war экспорта):

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> 
</beans> 

Источник: ответ Луи Grignon (в Injecting into a Jersey Resource class)