Требуется ли bean-discovery-mode=all для @Inject bean-компонента в ресурс Джерси @Path JAX-RS?

Я использую Payara 4.1.1.161. У меня есть ресурс Jersey @Path JAX-RS, и все, что я хочу сделать, это @Inject bean в него с помощью CDI. Я пробовал много разных комбинаций, чтобы заставить это работать, но пока единственный способ заставить его работать успешно — установить bean-discovery-mode="all" в beans.xml.

Я знаю, что "аннотированный" является предпочтительным режимом, а beans.xml еще более предпочтительным. Но каждый раз, когда я пытался использовать «аннотированный», у меня либо сбой при вызове ресурса JAX-RS, который выглядит следующим образом:

MultiException stack 1 of 1
org.glassfish.hk2.api.UnsatisfiedDependencyException: 
There was no object available for injection at
SystemInjecteeImpl(requiredType=InjectMe, parent=InjectResource,
qualifiers={}, position=-1, optional=false, self=false,
unqualified=null, 1000687916))

Или у меня произошел сбой при развертывании приложения, которое выглядит так:

Exception during lifecycle processing
java.lang.Exception: java.lang.IllegalStateException:
ContainerBase.addChild: start: org.apache.catalina.LifecycleException:
org.apache.catalina.LifecycleException:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: 
Unsatisfied dependencies for type InjectMe with qualifiers @Default
at injection point [BackedAnnotatedField] 
@Inject private org.thoth.jaspic.web.InjectResource.me

Вот моя настройка приложения.

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       bean-discovery-mode="all">
</beans>

Приложение JAX-RS

@javax.ws.rs.ApplicationPath("webresources")
public class ApplicationResourceConfig  extends org.glassfish.jersey.server.ResourceConfig {
    public ApplicationResourceConfig() {
        register(RolesAllowedDynamicFeature.class);
        registerClasses(
            org.thoth.jaspic.web.InjectResource.class
        );
     }
 }

Ресурс JAX-RS

@Path("inject")
public class InjectResource {
    @Inject
    private InjectMe me;

    @GET
    @Produces(MediaType.TEXT_HTML)
    public String getText(@Context SecurityContext context) {
        Principal p = context.getUserPrincipal();
        String retval = "<h3>inject</h3>";
        retval += String.format("<p>me=[%s]</p>", me);
        return retval;
    }
}

Простой компонент, который я хочу внедрить

public class InjectMe implements Serializable {

    private static final long serialVersionUID = 158775545474L;

    private String foo;

    public String getFoo() {
        return foo;
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }
 }

Опять же, если у меня есть мое приложение, как показано выше, с конфигурацией выше и с bean-discovery-mode="all", все кажется в порядке, и приложение развертывается без ошибок, а при вызове службы JAX-RS bean-компонент вводится без ошибок. Но когда я переключаюсь на bean-discovery-mode="annotated" ИЛИ, если у меня вообще нет файла beans.xml, все идет ужасно неправильно.

Итак, можете ли вы @Inject bean-компонент в JAX-RS-ресурс Jersy @Path с запущенной Payara 4.1.1.161 либо без beans.xml, либо с bean-discovery-mode="annotated"?


person Michael Remijan    schedule 22.09.2016    source источник


Ответы (1)


Ваш класс ресурсов JAX-RS должен иметь аннотацию, определяющую компонент, чтобы включить внедрение компонента CDI. Просто добавьте @ApplicationScoped или @RequestScoped к вашему ресурсу JAX-RS, и инъекция bean-компонента должна работать без режима обнаружения bean-компонентов.

Кстати, я предполагаю, что bean-компонент InjectMe также имеет аннотацию области действия в той или иной форме, поскольку она не показана в приведенном выше коде.

Например;

@Path("inject")
@ApplicationScoped
public class InjectResource {
person leet java    schedule 25.09.2016
comment
Просто примечание: аннотации JAX-RS не входят в число тех, которые превращают класс в bean-компонент CDI. Не все аннотации подходят, только аннотации области CDI и некоторые другие. Вот список: stackoverflow.com/a/29167950/784594. И требуемый bean-компонент (InjectMe), и bean-компонент, для которого требуется bean-компонент (InjectResource), должны быть аннотированы одним из них. - person OndroMih; 26.09.2016
comment
Спасибо. Я, должно быть, пробовал каждую комбинацию аннотаций, но я не думаю, что аннотировал саму конечную точку JAX-RS. Я был на 99,9% уверен, что аннотация @Path превратила его в ресурс, управляемый CDI, но, конечно же, я ошибался. Спасибо еще раз. - person Michael Remijan; 26.09.2016