Java Spring @Autowired如何使用从多个接口继承的接口?

时间:2017-10-15 12:19:50

标签: java spring dependency-injection

我有一个Java Spring Framework项目。经过一些谷歌搜索后,我找到了一种方法,将自定义JPA方法包含到JpaRepository中。使用@Autowired将我的存储库注入我的服务类,但我无法理解Spring在这种情况下如何处理注入。有人可以解释当方法实现在单独的类中时,Spring如何将CalendarEventRepository注入到CalendarEventService中。它在某个地方找到了JpaRepository实现,并使用我的自定义方法找到了我自己的自定义实现类。如何通过相同的引用变量calendarEventRepository访问它们的方法? Bonus问题:Spring如何查找并实例化JpaRepository的实现?

public interface CalendarEventRepository extends JpaRepository<CalendarEvent, Long>, CalendarEventRepositoryCustom { }

public interface CalendarEventRepositoryCustom {
public List<CalendarEvent> findCalendarEventsBySearchCriteria(CalendarEventSearchCriteria searchCriteria);
}

public class CalendarEventRepositoryImpl implements
CalendarEventRepositoryCustom {
public List<CalendarEvent> findCalendarEventsBySearchCriteria(CalendarEventSearchCriteria searchCriteria) {
     }
}

public class CalendarEventService {
@Autowired
CalendarEventRepository calendarEventRepository;
...
calendarEventRepository.delete(calendarEvent);
...
return  calendarEventRepository.findCalendarEventsBySearchCriteria(searchCriteria);
...
}

提前致谢!

2 个答案:

答案 0 :(得分:2)

当您使用Spring JPA存储库接口(class OperationCreate(CreateView, OperationMixIn): model = Operation form_class = OperationForm success_url = reverse_lazy('manage_operations') def get_form_kwargs(self): kwargs = super(OperationCreate, self).get_form_kwargs() kwargs.update({'user': self.request.user}) return kwargs def form_valid(self, form): operation = form.save(commit=False) operation.currency = Account.objects.get(pk=form.instance.account_id).currency self.update_account_balance(form) form.instance.user = self.request.user return super(OperationCreate, self).form_valid(form) 类)时,重要的是接口的实现是在运行时生成的。 Spring使用方法名来确定方法应该是什么(因为你已经正确地编写了名称extend JpaRepository,这意味着你已经知道了)。在您的特定情况下,findCalendarEventsBySearchCriteria扩展CalendarEventRepository因此具有方法CalendarEventRepositoryCustom,并且还扩展findCalendarEventsBySearchCriteria(...),这意味着它应被视为JPA存储库,并且相应的应该生成实现。

要启用存储库实现的生成,您需要将JpaRepository<CalendarEvent, Long>包含到XML配置文件中,或者<jpa:repositories base-package="..." />当您拥有这些时,这是Spring需要生成的所有信息(实例化)存储库并将其添加到应用程序上下文,并将其注入其他bean。在您的情况下,@Configuration @EnableJpaRepositories(basePackage = "...")指定应该注入的位置。我想这比主要问题更能解决红利问题,但似乎从一开始就更好。

我还没有碰过@Autowired CalendarEventRepository calendarEventRepository;。如果要删除特定方法的上述一代存储库实现,则应使用此类。 Spring查找一个名称等于存储库接口名称+“Impl”的类。如果存在这样的类,Spring会将其方法与生成的方法合并。因此,请亲自了解自动生成的CalendarEventRepositoryImpl方法是否符合您的需求,或者您想自己实现它。如果生成的适合,您应该考虑删除findCalendarEventsBySearchCriteria

答案 1 :(得分:1)

  1. 有人可以解释一下Spring如何注射 当CalendarEventRepository成为CalendarEventService时的方法 实现在不同的类中。
  2. 答案:首先,也是最重要的 - 所有的春豆都经过管理 - 他们生活在#34;在容器内部,称为&#34;应用程序上下文&#34;。

    无论您使用哪种类型的配置(基于Java或xml),您都可以启用&#34;组件扫描&#34;这有助于Spring确定要注入的资源。

    spring如何确定要注入的bean:

    • 匹配名称。
    • 匹配类型。

    您甚至可以使用限定符来缩小对spring的搜索范围。

    1. 它找到了我自己的JpaRepository实现 使用我的自定义方法自定义实现类。如何他们的 方法可通过相同的参考变量访问 calendarEventRepository?
    2. 这更像是java核心的继承问题。由于JpaRepositoryCalendarEventRepositoryCustomCalendarEventRepositoryCalendarEventRepositoryImpl的基类(实现),因此CalendarEventRepositoryImpl可以使用任何公开或受保护的方法/字段类。

      您正在使用&#34;通过界面编程&#34;这里你的引用变量是calendarEventRepository,这是一个接口(父),这就是你能够访问字段/方法的原因。

      1. 奖金问题:Spring如何找到并实例化 JpaRepository的实现?
      2. 在spring配置(基于java)中,您告诉spring搜索JPARepositories,如下所示:

        @EnableJpaRepositories(
                basePackages =  {
            "com.package"}
        , entityManagerFactoryRef = "EntityManagerFactory", transactionManagerRef = "jpaTransactionManager"
            )
        

        这就是spring知道要创建哪些bean的方式。

        我建议您阅读Craig Walls的Spring in Action(第2至第4版)。

        您也可以浏览https://spring.io/docs

        注释(Autowired,Inject,您的自定义)因AOP而起作用。阅读一下AOP,你会知道它是如何工作的。