Spring Data JPA配置的模块化

时间:2019-05-13 18:44:31

标签: spring-boot spring-data-jpa spring-data

我们正在寻找一种方法,让不同的模块分别指定@ ComponentScan,@ EnableJpaRepositories和EntityManagerFactory.setPackagesToScan。

我们将多个代码模块组合到我们的Web应用程序中。此外,我们允许客户特定的基本代码扩展,从而可以添加其他程序包。在测试中,我发现可以添加一个额外的java config类,并在@ComponentScan和@EnableJpaRepositories中拾取其他包。我在想,如果我可以使用@EntityScan,我会看到类似的行为。

但是,我们正在EntityManagerFactory中执行一些自定义,因此@EntityScan不再是一个选项。我不认为我们要指定另一个EntityManagerFactory是每个模块。 setPacakgesToScan方法执行软件包的替换(而不是添加到当前列表中)。

有很多关于问题地设置packagesToScan的功能的帖子,但这似乎大大增加了复杂性。

示例基本配置类

@Configuration
@EnableJpaRepositories(basePackages = { 
        "a", "b", "c"
 }
,repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class
)
@ComponentScan(basePackages = {
        "a", "b", "c"
}
)
public class BaseConfig {       
    @Bean
    public EntityManagerFactory entityManagerFactory() throws NamingException {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setJtaDataSource(dataSource());
        emf.setPackagesToScan(new String[] {"a", "b", "c"})
    }
}

示例扩展配置类

@Configuration
@EnableJpaRepositories(basePackages = { 
        "d"
 }
,repositoryFactoryBeanClass = BaseRepositoryFactoryBean.class
)
@ComponentScan(basePackages = {
        "d"
}
)
public class ExtensionConfig {      
    @Bean
    public EntityManagerFactory entityManagerFactory() throws NamingException {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setJtaDataSource(dataSource());
        emf.setPackagesToScan(new String[] {"d"})
    }
}

还有另一种方法可以实现这种行为吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

您可以尝试以下方法,尽管我不确定哪种方法最好:

为包装清单创建一个持有人类别。客户端扩展模块必须可以访问它:

public class EmfPackages {
    private final String[] packages;
    public EmfPackages(String[] packages) {
        this.packages = packages;
    }
    public String[] getPackages() {
        return this.packages;
    }
}

然后调整两个配置类:

public class BaseConfig {       
    @Bean
    public EMFPackages baseEmfPackages() {
        return new EmfPackages(new String[] {"a", "b", "c"});
    }    

    @Bean
    // both "holders" are now injected here
    // AFAIK this feature works in Spring 4+
    public EntityManagerFactory entityManagerFactory(List<EmfPackages> emfPackages) throws NamingException { 
        // actually this is Java 8+ style, adjust for lower versions if needed
        final String[] combinedPackages = emfPackages.stream()
            .flatMap(p -> Arrays.stream(p.getPackages()))
            .collect(Collectors.toList())
            .toArray(new String[0]{});

        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setJtaDataSource(dataSource());
        emf.setPackagesToScan(combinedPackages)
    }    
}

public class ExtensionConfig {      
    @Bean
    public EmfPackages extendedEmfPackages() {
        return new EmfPackages(new String[] {"d"});
    }
}