javax.inject.Qualifier Spring JavaConfig - PullRequest
       18

javax.inject.Qualifier Spring JavaConfig

2 голосов
/ 17 декабря 2011

У меня есть следующий код

2 javax.Inject Квалификаторы

@Qualifier
@Target(value={ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Hibernate {
--nothing goes here
}


@Qualifier
@Target(value={ElementType.FIELD,ElementType.TYPE,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Toplink{
--nothing goes here
}

Я квалифицирую репозитории

@Named
@Hibernate
public class HibernateRepository implements IRepository{
-- some code
}

@Named
@Toplink
public class ToplinkRepository implements IRepository{
-- some code
}

Эти репозиториивводятся с использованием javax.Inject

public class InvoiceService {
    @Inject
    //@Hibernate  I alternate between the two to test
    @Toplink
    private IRepository iRepository;
    public void saveInvoice(Invoice invoice){
    iRepository.save(invoice);
}

с использованием следующего класса конфигурации

@Configuration
public class Myconfig {

    @Bean
    public IRepository getHibernateRepository(){
        return new HibernateRepository();
    }

    @Bean
    public InvoiceService getInvoiceService(){
        return new InvoiceService();
    }

       @Bean
        public IRepository getToplinkRepository(){
        return new ToplinkRepository();
    }

}

Этот код прекрасно работает, когда я использую конфигурацию XML, любая идея о том, какзаставить его работать с javaConfig ??Или в моем коде что-то не так?При использовании выдает следующее исключение

Исключение в потоке "main" org.springframework.beans.factory.BeanCreationException: Ошибка при создании bean-компонента с именем 'getInvoiceService': сбой внедрения зависимостей с автопроводкой;вложенное исключение: org.springframework.beans.factory.BeanCreationException: не удалось автоматически связать поле: private com.domain.IRepository com.service.InvoiceService.iRepository;Вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: не найден соответствующий компонент типа [com.domain.IRepository] для зависимости: ожидается, что по крайней мере 1 компонент будет квалифицирован как кандидат для автоматического подключения для этой зависимости.Аннотации зависимостей: {@ javax.inject.Inject (), @ com.domain.Toplink ()}

Спасибо в ожидании.

1 Ответ

1 голос
/ 18 декабря 2011

В случае методов @Bean учитывается тип возвращаемого значения. Даже если вы, возможно, возвращаете TopLinkRepository из одного метода и HibernateRepository из другого, с точки зрения контейнера, все, что он знает, это то, что есть два компонента типа IRepository, и, следовательно, не понимает, что один аннотирован @Toplink и один из них аннотирован @ Hibernate.

У вас есть несколько вариантов здесь. Проще всего, учитывая вашу текущую конфигурацию, изменить типы возвращаемых данных, чтобы сделать их более конкретными.

Второй - оставить универсальные возвращаемые типы, но переместить аннотации квалификаторов @Toplink и @Hibernate на уровень метода @Bean.

Третий вариант - компонентное сканирование типов репозитория, вместо того, чтобы объявлять их как методы @Bean.

Третий подход обычно рекомендуется, учитывая, что вы уже используете @Inject для компонентов репозитория и пометили их @Named. Это делает их естественными кандидатами для компонентного сканирования в первую очередь. Проверьте Javadoc для @ComponentScan, чтобы узнать, как это сделать в мире классов @Configuration.

...