我们正在寻找一种方法,让不同的模块分别指定@ 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"})
}
}
还有另一种方法可以实现这种行为吗?
谢谢。
答案 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"});
}
}