2017-04-11 24 views
0

我碰到一个tutorial这似乎是适合我的用例,并试图实现它。我失败了,但不知道为什么。于是,我就找到类似的代码另一个例子,看着书“春行动,第四版由Craig墙”Spring @ComponentScan有什么可能的原因是无法自动创建一个由@Repository指定的类

的书描述了在300页相同的基本方法。首先定义一个JdbcTemplate Bean。

@Bean 
NamedParameterJdbcTemplate jdbcTemplate(DataSource dataSource) { 
    return new NamedParameterJdbcTemplate(dataSource); 
} 

然后,库实现一个接口

@Repository 
public class CustomRepositoryImpl implements CustomRepository { 

private final NamedParameterJdbcOperations jdbcOperations; 

private static final String TEST_STRING = ""; 

@Autowired 
public CustomRepositoryImpl(NamedParameterJdbcOperations jdbcOperations) { 
    this.jdbcOperations = jdbcOperations; 
} 

所以我不喜欢在书中提出的例子,写了一个测试,但得到的错误消息

错误创建名称为豆'de.myproject.config.SpringJPAPerformanceConfigTest':通过字段'abc'表示的不满足的依赖性;嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的类型为'de.myproject.CustomRepository'的合格bean:预计至少有1个bean有资格作为autowire候选者。依赖注解:{@ org.springframework.beans.factory.annotation.Autowired(必需=真)}

据我了解的书和教程描述,存储库应该由组件扫描被识别为一个Bean定义。

为了测试这个,我创建了一个上下文并询问了所有注册的Bean。

AnnotationConfigApplicationContext 
context = new AnnotationConfigApplicationContext(); 
context.getBeanDefinitionNames() 

假设我的存储库不在其中。因此,我只为了测试目的而增加了我的项目中的搜索范围,并将其设置为基本包。除储存库外,其他每个Bean都显示出来。

作为组件扫描和自动装配的替代方法,这些书描述了将存储库简单地声明为Bean的可能性,这是我所做的。

@Bean 
public CustomRepository(NamedParameterJdbcOperations jdbcOperations) { 
    return new CustomRepositoryImpl(jdbcOperations); 
} 

之后,Spring能够连线存储库。我看了本书的github code,希望有更好的理解,但不幸的是,只有运行的Bean解决方案在那里实现。

因此,这里是我的问题:

1)什么可能的原因是那里的bean定义,是这样的一个,而不是由组件识别扫描的场景?

2)该项目已经使用Spring JPA Data Repositories,有没有同时使用两种方法的原因?

+0

您可以检查您在@ComponentScan批注中通知哪些软件包,以及软件仓库是否在其子项中。 –

+0

@ComponentScan(basePackages = {“de.myproject。*”})并且存储库位于子包de.myproject.performance中,找到了来自不同子包的所有其他bean,但可能存在一些特殊规则对于@Repositorys我不知道 – aldr

回答

0

问题在于你的类的命名。这里有很多事情要理解。
1.您可以定义一个存储库Interface @Repository是可选的,只要它扩展了CRUDRepository或由spring-data提供的其中一个存储库。在这个类中你可以声明方法(find by ....)。而spring-data将基于底层数据库制定查询。您也可以使用@Query指定您的查询。
2。假设你有一个涉及复杂查询的方法或者spring-data不能开箱即用的方法,在这种情况下,我们可以使用底层模板类,例如JdbcTemplate或MongoTemplate ..
3执行此操作的过程是创建另一个界面和一个Impl类。这个接口的命名应该和Custom一样,并且你的Impl类应该被命名为Impl。并且所有的都应该在同一个包中。

例如,如果您的存储库名称是AbcRepository,那么您的自定义存储库应该命名为AbcRepositoryCustom,实现应该命名为AbcRepositoryImpl。AbcRepository扩展了AbcRepositoryCustom(以及其他弹簧数据存储库)。 AbcRepositoryImpl实现了AbcRepositoryCustom

0

我能够自己“解决”问题。

我们也有同样的basePackage注释为@ComponentScan

@EnableWebMvc 
@Configuration 
@ComponentScan(basePackages = {"de.myproject.*"}) 

所以实际上有两个相同的@ComponentScan裴松之注,我不知道掉前端类,这确实导致冲突。它接通了整个应用程序必须被加载的顺序已经改变,但那只是我猜测。

我干脆搬到我Repository及其Impl一个子包,并改变了

@ComponentScan(basePackages = {"de.myproject.subpackage.*"}) 

,现在一切工作正常。虽然它逃脱了我,但这种行为背后的确切原因是什么。

相关问题