向工作的Spring引导项目添加依赖项会使所有JUnit无效

向工作的Spring引导项目添加依赖项会使所有JUnit无效,spring,spring-boot,Spring,Spring Boot,我有两个Eclipse项目,每个项目都有Spring管理的服务。我为它们中的每一个使用SpringBootStarter依赖项。每一个都可以正常工作,并且可以通过SpringRunner.class和@SpringBootTest启动JUnit进行测试 现在,我想从项目2中的项目1调用一些服务,因此我在项目2中pom.xml中添加了一个依赖项,并添加了 @ComponentScanbasePackages=com.project1 从那时起,我就不能启动任何JUnit了,它抱怨没有设置数据源,就

我有两个Eclipse项目,每个项目都有Spring管理的服务。我为它们中的每一个使用SpringBootStarter依赖项。每一个都可以正常工作,并且可以通过SpringRunner.class和@SpringBootTest启动JUnit进行测试

现在,我想从项目2中的项目1调用一些服务,因此我在项目2中pom.xml中添加了一个依赖项,并添加了 @ComponentScanbasePackages=com.project1

从那时起,我就不能启动任何JUnit了,它抱怨没有设置数据源,就像配置了随机混合的地方一样

我的问题是:当您创建一个SpringBoot应用程序,并且希望在单独的项目中隔离一些特性时,推荐的做法是什么?如果你不能有两个spring boot应用程序,其中一个依赖于另一个,那么你需要什么样的spring依赖关系,这样spring boot项目才能处理非spring启动依赖关系,这样你仍然可以在本地使用spring runner启动JUnit

我需要一个接一个地选择Spring依赖项吗?核心、bean、上下文、测试、log4j、slf4j、junit、hamcrest等等。。。像之前的Spring boot存在这样做吗

请参阅我关于为什么可能的副本不同的评论

在从我的模块项目中删除所有Spring引导依赖项之后,只要添加ComponentScan来扫描模块服务,我仍然会有错误

下面是我的DB配置主项目,具体取决于要在包配置中清除的xml模块。在我将ComponentScan添加到模块项目中的包之前,此配置工作正常:

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="fr.my.project.repository")
class PersistenceContext {

  private static final String[] ENTITY_PACKAGES = { "fr.my.project.model" };

  private static final String PROP_DB_DRIVER_CLASS = "db.driver";
  private static final String PROP_DB_PASSWORD = "db.password";
  private static final String PROP_DB_URL = "db.url";
  private static final String PROP_DB_USER = "db.username";

  private static final String PROP_HIBERNATE_DIALECT = "hibernate.dialect";
  private static final String PROP_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
  private static final String PROP_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
  private static final String PROP_HIBERNATE_SHOW_SQL = "hibernate.show_sql";

  /**
   * Creates and configures the HikariCP datasource bean.
   * 
   * @param env
   *          The runtime environment of our application.
   * @return
   */
  @Bean(destroyMethod = "close")
  DataSource dataSource(Environment env) {
    HikariConfig dataSourceConfig = new HikariConfig();
    dataSourceConfig.setDriverClassName(env.getRequiredProperty(PROP_DB_DRIVER_CLASS));
    dataSourceConfig.setJdbcUrl(env.getRequiredProperty(PROP_DB_URL));
    dataSourceConfig.setUsername(env.getRequiredProperty(PROP_DB_USER));
    dataSourceConfig.setPassword(env.getRequiredProperty(PROP_DB_PASSWORD));

    return new HikariDataSource(dataSourceConfig);
  }

  /**
   * Creates the bean that creates the JPA entity manager factory.
   * 
   * @param dataSource
   *          The datasource that provides the database connections.
   * @param env
   *          The runtime environment of our application.
   * @return
   */
  @Bean
  LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource, Environment env) {
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
    entityManagerFactoryBean.setDataSource(dataSource);
    entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
    entityManagerFactoryBean.setPackagesToScan(ENTITY_PACKAGES);

    Properties jpaProperties = new Properties();

    // Configures the used database dialect. This allows Hibernate to create SQL
    // that is optimized for the used database.
    jpaProperties.put(PROP_HIBERNATE_DIALECT, env.getRequiredProperty(PROP_HIBERNATE_DIALECT));

    // Specifies the action that is invoked to the database when the Hibernate
    // SessionFactory is created or closed.
    jpaProperties.put(PROP_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROP_HIBERNATE_HBM2DDL_AUTO));

    // If the value of this property is true, Hibernate writes all SQL
    // statements to the console.
    jpaProperties.put(PROP_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROP_HIBERNATE_SHOW_SQL));

    // If the value of this property is true, Hibernate will use prettyprint
    // when it writes SQL to the console.
    jpaProperties.put(PROP_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROP_HIBERNATE_FORMAT_SQL));

    entityManagerFactoryBean.setJpaProperties(jpaProperties);

    return entityManagerFactoryBean;
  }

  /**
   * Creates the transaction manager bean that integrates the used JPA provider with the Spring transaction mechanism.
   * 
   * @param entityManagerFactory
   *          The used JPA entity manager factory.
   * @return
   */
  @Bean
  JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory);
    return transactionManager;
  }
}
并在加入:

@ComponentScan(basePackages="fr.my.module.xml.service")
我在启动任何Junit时都会遇到此错误:

Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.apache.tomcat.jdbc.pool.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.boot.autoconfigure.jdbc.DataSourceProperties$DataSourceBeanCreationException: Cannot determine embedded database driver class for database type NONE. If you want an embedded database please put a supported one on the classpath. If you have database settings to be loaded from a particular profile you may need to active it (no profiles are currently active).

下面是一个关于如何配置依赖项项目的临时答案,但我希望存在一些更简单的方法,为所有应用程序模块提供Spring引导快捷方式

具有手动最小依赖项的pom.xml:

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
手动应用程序配置:

@Configuration
@ComponentScan(basePackages="my.package.xml")
public class AppConfig {

}
在做了所有这些尝试之后,Spring Boot可能根本不是这个问题的原因

问题是我添加了@ComponentScanbasePackages=fr.package.xml,希望完成默认的包扫描,但它覆盖了它

添加包的正确方法是在添加新包之前明确地重新声明默认包:
@ComponentScanbasePackages={fr.package.xml,fr.package.persistence}

我的另一个答案是关于为Spring Boot应用程序中的模块设置手动最小依赖项。但下面是一个在模块中使用Spring boot特殊依赖项的示例,该模块不是主应用程序:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

来源:

我已经阅读了其他类似的问题,但没有找到这个问题的答案。根据您的配置@ComponentScanbasePackages=com.project1,可能存在重复的配置可能还不够。我显示的只是扫描依赖项项目中服务的附加配置。在我的主项目中,我有JPA的东西,我有实体和存储库的特定包规范,所以可能的重复没有帮助。目前您可能缺少副本中所述的@EnableJpaRepositoriesbasePackages=com.project1和@EntityScanbasePackages=com.project1@ComponentScanbasePackages=com.project1本身不这样做。
@Configuration
@ComponentScan(basePackages="my.package.xml")
public class AppConfig {

}
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
@RunWith(SpringRunner.class)
@SpringBootTest("service.message=Hello")
public class MyServiceTest {

    @Autowired
    private MyService myService;

    @Test
    public void contextLoads() {
        assertThat(myService.message()).isNotNull();
    }

    @SpringBootApplication
    static class TestConfiguration {
    }

}