Java Spring引导自动配置-bean创建顺序
我有一个使用JPA的软件和应用程序 出于超出这个问题的原因,我在单独的静态配置类中提供了自定义Java Spring引导自动配置-bean创建顺序,java,spring,spring-boot,Java,Spring,Spring Boot,我有一个使用JPA的软件和应用程序 出于超出这个问题的原因,我在单独的静态配置类中提供了自定义JPAVendorAdapter。并且配置表现为非确定性 在我的Windows deksktop上,当我启用--debug时,我看到了预期的结果: JpaBaseConfiguration#JPAVENDOR适配器 -@ConditionalOnMissingBean(类型:org.springframework.orm.jpa.JpaVendorAdapter;搜索策略:全部) 找到以下[custom
JPAVendorAdapter
。并且配置表现为非确定性
在我的Windows deksktop上,当我启用--debug
时,我看到了预期的结果:
JpaBaseConfiguration#JPAVENDOR适配器
-@ConditionalOnMissingBean(类型:org.springframework.orm.jpa.JpaVendorAdapter;搜索策略:全部)
找到以下[customJPAVendorAdapter](OnBeanCondition)
但一旦我将应用程序部署到某个服务器上,我就会得到:
JpaBaseConfiguration#JPAVENDOR适配器
-@ConditionalOnMissingBean(类型:org.springframework.orm.jpa.JpaVendorAdapter;搜索策略:全部)
未找到任何bean(在Bean条件下)
代码完全相同
请告诉我,在JpaBaseConfiguration
启动并自动配置默认适配器之前,必须创建带有JPAVendorAdapter
的@Bean
编辑:
@ComponentScan(
value = {"module.package"}
)
@EnableAutoConfiguration(exclude = {
SecurityAutoConfiguration.
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaBaseConfiguration.class
})
@EnableScheduling
@EnableConfigurationProperties
@Configuration
@Slf4j
public class MainConfig extends SpringBootServletInitializer implements SchedulingConfigurer {
...
}
@Configuration
@Slf4j
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
@ComponentScan(basePackageClasses = SelfHelpModuleComponentScanPlaceholder.class)
public class SelfHelpConfig {
public static class ModuleCondition extends AbstractModuleEnabledCondition {
@Override
public String getModuleId() {
return "self-help";
}
}
@Configuration
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
static class JpaVendorConfig {
@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(SpringHibernateJpaPersistenceProviderWithNamingStrategy jpaPersistenceProvider) {
log.info("Creating custom JPA vendor adapter");
return new HibernateJpaVendorAdapter() {
@Override
public PersistenceProvider getPersistenceProvider() {
return jpaPersistenceProvider;
}
};
}
}
}
配置非常分散,但希望我将介绍主要部分:
主配置:
@ComponentScan(
value = {"module.package"}
)
@EnableAutoConfiguration(exclude = {
SecurityAutoConfiguration.
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaBaseConfiguration.class
})
@EnableScheduling
@EnableConfigurationProperties
@Configuration
@Slf4j
public class MainConfig extends SpringBootServletInitializer implements SchedulingConfigurer {
...
}
@Configuration
@Slf4j
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
@ComponentScan(basePackageClasses = SelfHelpModuleComponentScanPlaceholder.class)
public class SelfHelpConfig {
public static class ModuleCondition extends AbstractModuleEnabledCondition {
@Override
public String getModuleId() {
return "self-help";
}
}
@Configuration
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
static class JpaVendorConfig {
@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(SpringHibernateJpaPersistenceProviderWithNamingStrategy jpaPersistenceProvider) {
log.info("Creating custom JPA vendor adapter");
return new HibernateJpaVendorAdapter() {
@Override
public PersistenceProvider getPersistenceProvider() {
return jpaPersistenceProvider;
}
};
}
}
}
使用JPA的模块:
@ComponentScan(
value = {"module.package"}
)
@EnableAutoConfiguration(exclude = {
SecurityAutoConfiguration.
DataSourceAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaBaseConfiguration.class
})
@EnableScheduling
@EnableConfigurationProperties
@Configuration
@Slf4j
public class MainConfig extends SpringBootServletInitializer implements SchedulingConfigurer {
...
}
@Configuration
@Slf4j
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
@ComponentScan(basePackageClasses = SelfHelpModuleComponentScanPlaceholder.class)
public class SelfHelpConfig {
public static class ModuleCondition extends AbstractModuleEnabledCondition {
@Override
public String getModuleId() {
return "self-help";
}
}
@Configuration
@Conditional(value = SelfHelpConfig.ModuleCondition.class)
static class JpaVendorConfig {
@Bean
public AbstractJpaVendorAdapter customJPAVendorAdapter(SpringHibernateJpaPersistenceProviderWithNamingStrategy jpaPersistenceProvider) {
log.info("Creating custom JPA vendor adapter");
return new HibernateJpaVendorAdapter() {
@Override
public PersistenceProvider getPersistenceProvider() {
return jpaPersistenceProvider;
}
};
}
}
}
此模块@ComponentScan
发现数据库配置:
@Configuration
@EntityScan(basePackageClasses = SelfHelpModuleComponentScanPlaceholder.class)
@EnableJpaRepositories(basePackageClasses = SelfHelpModuleComponentScanPlaceholder.class)
@Import({DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class DBConfig {
}
如果JPAVendorConfig没有放在单独的类中,则根本不会应用它。如果在单独的类中,那么它在我的桌面上工作,但在部署到Linux服务器时不工作。发布您的配置…首先,为什么您有两次这种情况,为什么在配置中嵌套配置,将其作为bean添加到out配置中也应该工作。但是你真的需要这个吗?这个适配器有什么特别之处,你需要一个定制的适配器吗?在我看来,你可以通过设置适当的属性来获得相同的结果,这会使事情变得更复杂。正如所解释的,如果不嵌套,它根本不起作用。曾经嵌套的工作“有时”。我需要为每个环境的表添加自定义前缀。例如,实现类似于
@Table(name=“${prefix}\u myTable”)
的功能,那么为什么不简单地注册一个自定义命名策略
,它可以通过应用程序.属性
简单地配置?而不是试图用条件句。您仍然不需要对条件进行双重检查(仅对嵌套的条件进行检查就足够了),但是只有一个在bean方法上具有条件的配置类也可以工作。命名策略采用的是类而不是bean,因此您无法向其中注入属性。