Почему я получаю исключение «Неоднозначные зависимости для интерфейса», когда я уже использую аннотацию @Produces? - PullRequest
0 голосов
/ 23 января 2019

Я использую в своем проекте два межплатформенных ПО для обмена сообщениями.RabbitMQ и Apache Kafka.У меня есть потребительский интерфейс IConsume, который реализован ConsumerRabbitMQ и ConsumerKafka.При запуске, выполняющем некоторые условия, я использую аннотацию @Produces, чтобы выбрать реализацию для интерфейсного компонента, которую я буду внедрять, но она дает мне эту ошибку.

Исключение 1:

org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type IConsume with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject private com.mycompany.chatapp.startup.RunConsumers.ct
  at com.mycompany.chatapp.startup.RunConsumers.ct(RunConsumers.java:0)
  Possible dependencies: 
  - Session bean [class com.mycompany.chatapp.messagegateway.ConsumerRabbitMQ with qualifiers [@Any @Default]; local interfaces are [IConsume],
  - Producer Method [IConsume] with qualifiers [@Any @Default] declared as [[BackedAnnotatedMethod] @Produces public com.mycompany.chatapp.startup.MOMConfigBean.produceIConsume()],
  - Session bean [class com.mycompany.chatapp.messagegateway.ConsumerKafka with qualifiers [@Any @Default]; local interfaces are [IConsume]

@ По умолчанию и @Alternative работает, но я хочу, чтобы он выбрал, проверив, какое из промежуточных программ работает.

Поиск работает, я также попробовал beanName.Я думаю, что проблема с @Produces, но я не могу найти, что.

import javax.enterprise.inject.Produces;

@Singleton
@Startup
public class MOMConfigBean {
private String mom;


@PostConstruct
public void init() {
    mom = "Kafka";
}

@EJB(lookup = "java:global/Chatapp/ConsumerKafka!com.mycompany.chatapp.messagegateway.IConsume")
IConsume kafkaConsumer;

@EJB(lookup = "java:global/Chatapp/ConsumerRabbitMQ!com.mycompany.chatapp.messagegateway.IConsume")
IConsume rabbitConsumer;

@Produces
public IConsume produceIConsume() {
    if ("Kafka".equals(mom)) {
        return kafkaConsumer;
    } else {
        return rabbitConsumer;
    }
}


public interface IConsume {
// some code
}

@Stateless
public class ConsumerKafka implements IConsume{
// some code
}

@Stateless
public class ConsumerRabbitMQ implements IConsume {
// some code
}

public class runConsumers{

@Inject
private IConsume ct;

}

1 Ответ

0 голосов
/ 27 января 2019

У вас есть три неоднозначных источника IConsume экземпляров:

  1. a ConsumerKafka EJB
  2. a ConsumerRabbitMQ EJB
  3. и @Produces public IConsume produceIConsume() метод.

Вам необходимо устранить неоднозначность источника экземпляров IConsume, используя квалификатор.

Этот классификатор будет выглядеть примерно так:

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.inject.Qualifier;

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD})
public @interface ConditionalMom {
}

Тогда квалифицируйте производителя:

@Produces
@ConditionalMom
public IConsume produceIConsume() {
    if ("Kafka".equals(mom)) {
        return kafkaConsumer;
    } else {
        return rabbitConsumer;
    }
}

и место введения:

public class runConsumers{

    @Inject
    @ConditionalMom
    private IConsume ct;

}

Теперь у вас есть единственный источник @ConditionalMom IConsume экземпляров, поэтому он больше не является двусмысленным.

Вы обнаружите, что будете использовать квалификаторы повсеместно, когда начнете использовать возможности CDI.

...