我有一个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);
...
}
提前致谢!
答案 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)
答案:首先,也是最重要的 - 所有的春豆都经过管理 - 他们生活在#34;在容器内部,称为&#34;应用程序上下文&#34;。
无论您使用哪种类型的配置(基于Java或xml),您都可以启用&#34;组件扫描&#34;这有助于Spring确定要注入的资源。
spring如何确定要注入的bean:
您甚至可以使用限定符来缩小对spring的搜索范围。
这更像是java核心的继承问题。由于JpaRepository
,CalendarEventRepositoryCustom
和CalendarEventRepository
是CalendarEventRepositoryImpl
的基类(实现),因此CalendarEventRepositoryImpl
可以使用任何公开或受保护的方法/字段类。
您正在使用&#34;通过界面编程&#34;这里你的引用变量是calendarEventRepository
,这是一个接口(父),这就是你能够访问字段/方法的原因。
在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,你会知道它是如何工作的。