Использование 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 или проблемы со сваркой?