基于类型参数自动装配 CrudRepository

我想CrudRespository<Type,Key>在抽象父类中自动装配 a ,然后将它与子类一起使用。错误告诉我:


java.lang.IllegalStateException: Failed to load ApplicationContext

[...]

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountExtractor': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.repository.CrudRepository<com.finnwa.adwords.adconnect.Account, java.lang.Long>' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

定义依赖项的抽象父级。


@Component

public abstract class Extractor<T,KEY> {


    @Autowired

    protected CrudRepository<T,KEY> repository;

   // some business logic

}

提供参数的子类。


@Component

class AccountExtractor extends Extractor<Account, Long>{

    // some config

}

其他可能相关的类:


public interface AccountRepository extends CrudRepository<Account, Long>{}


@SpringBootApplication

@EnableJpaRepositories(basePackages = "package.my")

public class Application {

    public static void main(String[] args) {

         SpringApplication.run(Application.class);

    }

}

我从其他问题中了解到,父类中的依赖项可能不是私有的。所以我把它保护起来。我缺少什么吗?


编辑:所以 Paul Janssens 和 M. Deinum 发布了一些不错的解决方法。但为什么这不起作用?这里出了什么问题?


GCT1015
浏览 202回答 3
3回答

慕仙森

对于初学者,我建议不要使用字段注入,而是使用构造函数注入。我还建议使用特定类型,与泛型一样,更改是删除了类型信息。我可能会做类似的事情public abstract class Extractor<T,KEY> {&nbsp; private final CrudRepository<T,KEY> repository;&nbsp; protected Extractor(CrudRepository<T, KEY> repository) {&nbsp; &nbsp; this.repository=repository;&nbsp; }}然后在您的特定类中使用AccountRepository并将其传递给超类。@Componentclass AccountExtractor extends Extractor<Account, Long>{&nbsp; AccountExtractor(AccountRepository repository) {&nbsp; &nbsp; super(repository);&nbsp; }}这样在你的超类和方法中你仍然可以使用基类型CrudRepository。额外的优势还在于,您现在可以非常轻松地为 编写单元测试AcountExtractor并简单地模拟 ,AccountRepository而无需引导 Spring Boot 应用程序。(我知道你可以使用,@DataJpaTest但简单的模拟更快)。

泛舟湖上清波郎朗

只需使用抽象方法并在子类中执行接线public abstract CrudRepository<T,KEY> getRepository();...FooRepository implements CrudRepository<Foo,Integer>...@Autowiredprotected FooRepository repository;@Overridepublic CrudRepository<Foo,Integer> getRepository() {&nbsp; &nbsp; return repository;}

jeck猫

我会说AccountRepository缺少“魔法注释”:@Repository // This tells Spring Data to actually create a "standard" repository instance for uspublic interface AccountRepository extends CrudRepository<Account, Long>{}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java