2015-08-20 3 views
3

Я использую перехватчики CDI, и я понял, что только первый вызов метода в классе, аннотированном с помощью @Interceptor, перехвачен. В приведенном ниже примере метод B никогда не перехватывается.Java CDI. Перехватчик вызывается только при первом вызове метода в классе

@InterceptorBinding 
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Transactional { 

} 


@Transactional 
@Interceptor 
public class TransactionsInterceptor { 

    @AroundInvoke 
    public Object transactionInterceptor(InvocationContext context) throws Exception { 

      System.out.println("Method="+context.getMethod().getName()); 
      return context.proceed(); 

    } 
} 


public Interface AnImportantInterface { 
     public void methodA(); 
     public void methodB(); 
} 

@Transactional 
@ThreadScoped 
public class AnImportantClass implements AnImportantInterface { 

    public void methodA() { 

     methodB(); 
    } 

    public void methodB() { 

     //This method is never intercepted 
    } 

} 


public class AnotherImportantClass { 
    @Inject AnImportantInterface aui; 

    public void someMethod() { 
     aui.methodA(); 
    } 
} 

Как я могу достичь этого методаB быть перехваченным, если метод А вызывается первым? есть ли какое-то обходное решение?

ответ

4

Это потому, что вы вызываете methodB() напрямую, а не через прокси-сервер CDI, поэтому перехватчик никогда не вызывается. Перехватчики будут вызываться только при вызове метода бина CDI с использованием его прокси. Вы должны переместить метод B в другой CDI bean и @Inject в этот и от methodA изменить methodB() на bean2.methodB(..).

+0

В основном исправлено, хотя его ценность заключается в том, что самоинъекция не предусмотрена в качестве функции в спецификации CDI. –

+0

@JohnAment. Поскольку вы указываете, что самоинъекция не предусмотрена в текущей спецификации CDI, хотя это не то, на что я получаю ответы, если она была поддержана (как в спецификации EJB), это сделало бы для более чистого решения. Для тех, кого интересует RFE для этого: https://issues.jboss.org/browse/CDI-414 – NBW

1

Использовать самостоятельно инъекции. Быстрая инъекция Bean может быть достигнута в CDI довольно просто - просто введите Instance, где T - реализация.

@Named 
public class Foo implements Fooable{ 

@Inject 

private Instance<Foo> foo; 

public void executeFirst(){ 

foo.get().executeSecond(); 

} 

@Transactional 

public void executeSecond(){ 

//do something 

} 

} 

Таким образом, вы можете выполнить свой метод прямо в одном и том же компоненте. Обязательно выберите правильную область действия, если компонент включен. Также убедитесь, что общий тип экземпляра T является непосредственно реализацией - это обеспечивает реализацию правильного объекта каждый раз.

 Смежные вопросы

  • Нет связанных вопросов^_^