CDI Перехватчики и Джерси JAX / RS - PullRequest
0 голосов
/ 09 сентября 2018

Использование CDI API и Weld 3.0.x как импл.

У меня есть простой управляемый компонент CDI / @ Named, в котором есть метод, помеченный для перехвата. Перехватчик - это простая система регистрации, подобная перехватчику. Это все просто отлично работает и, как и ожидалось, в «контейнере» (например, jboss или wildfly) он также работает в программе Java SE (загрузка CDI через SeContainerInitializer и т. д.).

Теперь, используя ТОЧНО ЖЕ управляемый бин и перехватчик, НО точка ввода управляемого бина находится в очень простом контроллере JAX / RS (Jersey Runtime 2.27 с jersey-cdi2-se); перехватчик не стреляет

В этой среде инъекция разрешается нормально, как и большинство других простых вещей cdi, таких как производители и пост-конструкции, наблюдения и т. Д. Метод конечной точки rest может вызывать методы инъекции, но перехватчик не сработает.

В игре нет сервлета или контейнера EE; только Джерси и CDI / Weld - так что это очень похоже на случай JavaSE - ничто не загружает причал / гризли или другой простой загрузочный контейнер HTTP.

Немного больше предыстории:

По сути, у меня есть ванильный CDI BDU / JAR с некоторыми @Nameds в нем; некоторые из которых имеют некоторые аннотации перехватчика. DBU не содержит impl для аннотаций Перехватчика. Я хочу иметь возможность включать BDU в несколько различных проектов, в то же время позволяя хост-проекту предоставлять конкретную реализацию перехватчиков (или опускать ее), которая наиболее целесообразна для проекта.

Эта стратегия работает нормально для хост-проектов, которые нацелены на контейнер EE или JavaSE. Теперь у меня есть этот странный гибрид JavaSE / JAX-RS / Jersey; все, кроме перехватчика работает. Как будто есть некоторые помехи в вещах jersey-cdi2-se (или где-то еще); или, может быть, какой-то «переключатель», который нужно бросить. Регистрация сварного шва предполагает, что перехватчик находится в игре.

Есть ли что-то особенное или другое в том, чтобы заставить перехватчики CDI работать вместе с JAX-RS / Jersey?

Этот нечетный SE / jax-rs mashup на самом деле использует неуправляемый Java-контейнер AWS, поэтому «http-контейнер» предоставляется AWS API Gateway и прокси-сервером lambda.

(ПРИМЕЧАНИЕ. Мне известно, что использование некоторых / всех / любых из перечисленных выше технологий в среде FAAS / Lambda может быть сомнительным. это.)

Редактировать и обновить: Перехватчик включен? Да, насколько я могу судить, это так. Я удалил следующие биты из журнала (после включения записи в WELD):

[main] DEBUG org.jboss.weld.Bootstrap - WELD-000105: Enabled interceptor types for Weld BeanManager for /var/task [bean count=5]:
- class org.jboss.weld.contexts.activator.ActivateRequestContextInterceptor,
- class org.jboss.weld.contexts.activator.CdiRequestContextActivatorInterceptor,
- class org.jboss.weld.environment.se.contexts.activators.ActivateThreadScopeInterceptor,
- class com.pin.faas.MyTransactionalInterceptor

.....

[main] DEBUG org.jboss.weld.Bootstrap - WELD-000107: Interceptor: Interceptor [class com.pin.faas.MyTransactionalInterceptor intercepts @MyTransactional

Что касается некоторых битов кода:

Перехват связывания:

package com.pin.api.annotation;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.interceptor.InterceptorBinding;


@Inherited
@InterceptorBinding
@Target({ TYPE, METHOD })
@Retention(RUNTIME)
public @interface MyTransactional
{

}

Перехватчик импл:

package com.pin.faas;

import java.util.logging.Logger;
import javax.interceptor.*;
import com.pin.api.annotation.MyTransactional;

@Interceptor
@MyTransactional
public class MyTransactionalInterceptor
{
    private static final Logger LOGGER = Logger.getLogger("DateServices");

    public MyTransactionalInterceptor()
    {
        LOGGER.info("TransactionalInterceptor constructed");
    }

    @AroundInvoke
    public Object handleTransactionBoudary(InvocationContext context) 
         throws Exception
    {
        LOGGER.info("handleTransactionBoudary called!");
        return context.proceed();
    } 
}

Управляемый компонент CDI с маркером-перехватчиком:

package com.pin.services.impl.businesslogic;

import com.pin.api.DatesService;
import com.pin.api.businesslogic.validations.BadCodeException;
import javax.inject.Inject;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
import com.pin.api.annotation.MyTransactional;

@Named
@RequestScoped
public class DatesServiceImpl implements DatesService
{
    @Inject
    private SomeDao dao;

    @Override    
    @MyTransactional
    public String insertRecordIntoXferLog(Integer exceptionCode)
        throws BadCodeException
    {        
        dao.insertABrnch();
        if(exceptionCode !=null && -1 == exceptionCode)
        {
            throw new BadCodeException("exception trigger value happenend, tossing an exception and expecting a rollback"); 
        }
        return("inserted");
    }
}

Наконец, контроллер JAX-RS вводит сервис:

package com.pin.api.rest;

import javax.enterprise.context.RequestScoped;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.logging.Logger;
import javax.inject.Inject;
import com.pin.api.DatesService;
import com.pin.api.businesslogic.validations.BadCodeException;
import java.util.logging.Level;

@Path("/tx")
@RequestScoped
public class TxTestController
{    
    private static final Logger LOGGER = Logger.getLogger("DateServices");                 

    @Inject
    private DatesService service;     

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response testAtTransactional(@QueryParam("c") Integer code)
    {    
        Integer val = 1; 
        LOGGER.info("testAtTransactional invoked");
        if(null == code)
        {
            LOGGER.info("testAtTransactional DID NOT get a code value, assuming value = " + val);
        }
        else
        {
            val = code; 
            LOGGER.info("testAtTransactional DID get a code value = " + val);
        }     
        String result = "called service.insertRecordIntoXferLog(" + val +  ")"; 
        try
        {
            service.insertRecordIntoXferLog(val); 
        }
        catch(BadCodeException bce)
        {
            result = bce.getMessage(); 
        }
        catch(Exception other)
        {
            result = other.getMessage(); 
            LOGGER.log(Level.SEVERE,"ERROR",other); 
        }
        return Response.status(200).entity(result).build();        
    }    
}

ОБНОВЛЕНИЕ

Согласно некоторым комментариям, я добавил аннотацию @Priority. Это ничего не изменило. Я также настраивал упаковку различными способами на случай, если возникли проблемы с загрузкой BDU / Jar и инициализацией bean-компонента CDI; эти изменения упаковки не имели значения.

Я думаю, что есть помехи JAX-RS CDI2-SE и перехватчикам. Глядя на то, как jax-rs-cdi2-se загружает контейнер CDI, он ничего не делает для перехватчиков. Возможно, это тоже не нужно, так как перехватчик находится в beans.xml. Однако в автономном примере SE CDI2 (без jax-rs - просто консольное приложение) я обнаружил, что мне нужно явно включить перехватчик через initializer.enableInterceptors (), чтобы перехватчик работал. Явное включение перехватчиков было необходимо даже при активации перехватчика beans.xml. Может быть, это больше проблема JAX-RS или проблемы со сваркой?

...