首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Spring Data JPA存储库中使用@Primary

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

Stack Overflow用户
提问于 2015-05-04 20:12:29
回答 1查看 1.3K关注 0票数 5

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

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

代码如下:

代码语言:javascript
运行
复制
@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<BeanDefinition> getRepositoryBeans(ConfigurableListableBeanFactory beanFactory) {
        List<BeanDefinition> 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<BeanDefinition> 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);
        }
    }
EN

回答 1

Stack Overflow用户

发布于 2019-07-05 23:15:26

我尝试将该解决方案应用于具有两个Mongo存储库的spring boot应用程序。但它无法在propertyValues中找到repositoryInterface。进一步的调查发现,有一个属性可以标识存储库接口factoryBeanObjectType

因此,将方法makeRepositoriesPrimary()中的代码从:

代码语言:javascript
运行
复制
String repositoryInterface = (String) repositoryBeanDefinition.getPropertyValues().get(REPOSITORY_INTERFACE_PROPERTY);

至:

代码语言:javascript
运行
复制
String repositoryInterface = (String) repositoryBeanDefinition.getAttribute("factoryBeanObjectType");

和预期的一样。

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30029878

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档