Ошибка конфигурации Guice Никакой реализации не было связано - PullRequest
1 голос
/ 13 июня 2019

Я пытаюсь сохранить единый сервис AmazonSNS для доступа к SNS. Я написал модуль для SNS (в настоящее время добавлен только один SNS) и средство доступа для публикации сообщения. Мой код выглядит следующим образом:

public class SNSModule extends AbstractModule {

    @Override
    protected void configure() {
    }

    @Provides
    @Named("PSSNSRegionName")
    private Regions getPSSNSRegionName(
            @Named(BeanConstants.P_S_SNS_REGION) final String regionName) {
        return Regions.fromName(regionName);
    }

    @Provides
    @Singleton
    @Named(BeanConstants.P_S_SNS)
    public AmazonSNS getPSSNS(
            @NonNull @Named("PaymentSuccessSNSRegionName") final Regions region,
            final Config config) {
        return AmazonSNSClientBuilder.standard()
                .withCredentials(new AWSCredentialsProviderImpl(config.getSnsMaterialSet()))
                .withRegion(region)
                .build();
    }

}

SNS Accessor выглядит следующим образом:

@RequiredArgsConstructor(access = AccessLevel.PUBLIC, onConstructor = @__(@Inject))
public class SNSAccessor {

    @Named(BeanConstants.P_S_SNS)
    private final AmazonSNS snsClient;
    private static final String COLON = ":";
    private static final short ARN_LENGTH = 6;

    public PublishResult publishToSNS(@NonNull final String snsTopicArn, @NonNull final String messageToPublish) {
        try {
            String[] arnParts = snsTopicArn.split(COLON);
            Preconditions.checkArgument(
                    snsTopicArn.split(COLON).length == ARN_LENGTH,
                    "Expected arn to have 6 parts but found: " + arnParts.length
            );
            return snsClient.publish(snsTopicArn, messageToPublish);
        } catch (InternalErrorException e) {
            log.error("InternalErrorException publishing notification to SNS", e);
            throw new RetriableException(e);
        } catch (Exception e) {
            log.error("Exception publishing notification to SNS", e);
            throw new NonRetriableException(e);
        }
    }
}

Мне удалось собрать пакет, но он вызвал исключение ConfigurationException во время выполнения.

Caused by: com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for com.amazonaws.services.sns.AmazonSNS was bound.
  while locating com.amazonaws.services.sns.AmazonSNS
    for parameter 0 at com.xyz.service.sns.SNSAccessor.<init>(SNSAccessor.java:29)

Не могли бы вы помочь мне понять, что я делаю не так? Я правильно установил SNSModule в главном.

Ответы [ 3 ]

2 голосов
/ 13 июня 2019

Параметр Lombok @RequiredArgsConstructor с onConstructor не работает с аннотированными инъекциями зависимостей.Вам нужно явно написать конструктор для этого случая.

1 голос
/ 14 июня 2019

Решение довольно сложное, у меня с примером работало следующее:
lombok 1.8.4 Guice 4.2.2

Вы должны создать свою собственную аннотацию и заменить на нее аннотацию @Namedсм. BindingAnnotations
например,

package org.company.PSSNS

import com.google.inject.BindingAnnotation;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@BindingAnnotation
@Target({PARAMETER,METHOD,FIELD})
@Retention(RUNTIME)
public @interface PSSNS {}

Затем добавьте файл lombok.config, см. здесь

в файле добавьте следующую строку

lombok.copyableAnnotations += org.company.PSSNS

в вашем классе

@RequiredArgsConstructor(access = AccessLevel.PUBLIC, onConstructor = @__(@Inject))
public class SNSAccessor {

    @PSSNS
    private final AmazonSNS snsClient;
    private static final String COLON = ":";
    private static final short ARN_LENGTH = 6;

Замените его и в модуле Guice

public class SNSModule extends AbstractModule {


    @Provides
    @Singleton
    @PSSNS
    public AmazonSNS getPSSNS(
            @NonNull @Named("PaymentSuccessSNSRegionName") final Regions region,
            final Config config) {
        return AmazonSNSClientBuilder.standard()
                .withCredentials(new AWSCredentialsProviderImpl(config.getSnsMaterialSet()))
                .withRegion(region)
                .build();
    }

}

Когда я проверял, что мне нужно очистить сборку от maven

Посмотрите на сгенерированный класс и убедитесь, что вы видите его в конструкторе.
Это должно позволить Guice ввести все аргументы вашего конструктора.

1 голос
/ 13 июня 2019

Конфигурации, которые вы отображаете и связываете в SNSModule, выглядят корректно.

Поскольку вы не опубликовали основной код класса приложения. Я подозреваю, что вы могли пропустить создание инжектора в SNSModule. Добавьте следующие строки в main-application-class:

Injector injector = Guice.createInjector(SNSModule);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...