2

我有以下代码

2javax.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
}

I 限定存储库

@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 一起工作吗?或者我的代码中有什么根本错误?使用时会引发以下异常

线程“主”org.springframework.beans.factory.BeanCreationException 中的异常:创建名为“getInvoiceService”的 bean 时出错:注入自动装配的依赖项失败;嵌套异常是 org.springframework.beans.factory.BeanCreationException:无法自动装配字段:私有 com.domain.IRepository com.service.InvoiceService.iRepository;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有为依赖项找到类型为 [com.domain.IRepository] ​​的匹配 bean:预计至少有 1 个 bean 有资格作为此依赖项的自动装配候选者。依赖注解:{@javax.inject.Inject(), @com.domain.Toplink()}

感谢期待。

4

1 回答 1

1

对于@Bean 方法,返回类型很重要。即使您可能从一个方法返回一个 TopLinkRepository,从另一个方法返回一个 HibernateRepository,但从容器的角度来看,它只知道有两个 IRepository 类型的 bean,因此不明白一个是 @Toplink 注释的并且一个是 @Hibernate 注释的。

您在这里有几个选择。给定您当前的配置,最简单的方法是更改​​返回类型以使其更具体。

第二个是保留返回类型通用,但将@Toplink 和@Hibernate 限定符注释移动到@Bean 方法级别。

第三个是对存储库类型进行组件扫描,而不是将它们声明为@Bean 方法。

通常建议使用第三种方法,因为您已经在存储库组件上使用了@Inject,并用@Named 标记它们。这使得它们首先成为组件扫描的自然候选者。查看@ComponentScan 的Javadoc,了解如何在@Configuration 类世界中执行此操作。

于 2011-12-17T22:41:49.650 回答