在Spring Data JPA存储库中使用@Primary

如果有人需要在Spring Data存储库上使用@Primary:看起来Spring Data JPA会忽略存储库上的@Primary注释。

作为一种解决方法,我创建了BeanFactoryPostProcessor ,它检查给定的存储库是否有@Primary注释并将该bean设置为主要。

这是代码:

 @Component public class SpringDataPrimaryPostProcessor implements BeanFactoryPostProcessor { public static final String REPOSITORY_INTERFACE_PROPERTY = "repositoryInterface"; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { makeRepositoriesPrimary(getRepositoryBeans(beanFactory)); } protected List getRepositoryBeans(ConfigurableListableBeanFactory beanFactory) { List springDataRepositoryDefinitions = Lists.newArrayList(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); String beanClassName = beanDefinition.getBeanClassName(); try { Class beanClass = Class.forName(beanClassName); if (isSpringDataJpaRepository(beanClass)) { springDataRepositoryDefinitions.add(beanDefinition); } } catch (ClassNotFoundException e) { throw new ApplicationContextException(String.format("Error when trying to create instance of %s", beanClassName), e); } } return springDataRepositoryDefinitions; } protected void makeRepositoriesPrimary(List repositoryBeans) { for (BeanDefinition repositoryBeanDefinition : repositoryBeans) { String repositoryInterface = (String) repositoryBeanDefinition.getPropertyValues().get(REPOSITORY_INTERFACE_PROPERTY); if (isPrimary(repositoryInterface)) { log.debug("Making site repository bean primary, class: {}", repositoryInterface); repositoryBeanDefinition.setPrimary(true); } } } protected boolean isSpringDataJpaRepository(Class beanClass) { return RepositoryFactoryInformation.class.isAssignableFrom(beanClass); } private boolean isPrimary(String repositoryInterface) { return AnnotationUtils.findAnnotation(getClassSafely(repositoryInterface), Primary.class) != null; } private Class getClassSafely(String repositoryInterface) { try { return Class.forName(repositoryInterface); } catch (ClassNotFoundException e) { throw new ApplicationContextException(String.format("Error when trying to create instance of %s", repositoryInterface), e); } }