【问题标题】:Inject EJB into Jersey Resource Class将 EJB 注入 Jersey 资源类
【发布时间】:2016-03-23 14:35:03
【问题描述】:

我有以下Jersey 资源:

@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。我正在使用Jersey 1.11 运行Glassfish 3.1.2

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

【问题讨论】:

    标签: jakarta-ee jersey glassfish jax-rs glassfish-3


    【解决方案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>
    

    来源:Louis GRIGNON 的回答 (Injecting into a Jersey Resource class)

    【讨论】:

      猜你喜欢
      • 2014-02-20
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2014-06-27
      • 1970-01-01
      • 1970-01-01
      • 2012-05-19
      相关资源
      最近更新 更多