【问题标题】:Two Spring Boot projects both with @SpringBootApplication两个带有 @SpringBootApplication 的 Spring Boot 项目
【发布时间】:2017-06-03 11:05:13
【问题描述】:

我有一个数据项目和 UI 项目。这两个项目都是 Spring Boot 应用程序。这两个项目具有相同的根包 (com.myorg),主类使用 @SpringBootApplication 注释。

数据项目的主类是:

package com.myorg;
@SpringBootApplication
public class DataApplication {

    public static void main(String[] args) {
        SpringApplication.run(DataApplication.class, args);
    }

}

UI项目的主类是:

package com.myorg;
@SpringBootApplication
public class UiApplication {

    public static void main(String[] args) {
        SpringApplication.run(UiApplication .class, args);
    }

}

UI 项目通过以下 Gradle 依赖依赖于数据项目:

dependencies {
    compile('com.myorg:data:1.0')
}

如果我运行 UI 应用程序,它可以正常运行。但是,如果我在 UI 应用程序中运行集成测试,如下所示:

package com.myorg
@RunWith(SpringRunner.class)
@SpringBootTest
public class UiIntTest {

    @Test
    public void contextLoads() {
    }

}

出现如下初始化错误:

java.lang.IllegalStateException: Found multiple @SpringBootConfiguration annotated classes

在数据项目的主类中,如果我将@SpringBootApplication替换为

@Configuration
@EnableAutoConfiguration
@ComponentScan({ "com.myorg" })

我在尝试运行其集成测试时收到以下初始化错误:

java.lang.IllegalStateException: Unable to find a @SpringBootConfiguration, you need to use @ContextConfiguration or @SpringBootTest(classes=...) with your test

例如,如果我尝试运行:

package com.myorg
@RunWith(SpringRunner.class)
@SpringBootTest
public class DataIntTest {

    @Test
    public void contextLoads() {
    }

}

如何正确配置数据和 UI 项目?

【问题讨论】:

  • 显示更多代码。添加你的包结构和层次结构
  • @Olayinka - 我添加了更多代码和包结构细节。如果我仍然缺少一些相关细节,请告诉我。
  • 同一个包中不能有两个springapplication注解
  • 作为记录,您可以在同一个包中拥有 2 个 SpringBootApplication。这是否是一个好主意是另一回事。当有多个时,需要在pom.xml中指定main-class属性

标签: spring spring-boot


【解决方案1】:

您需要指定使用哪个 Spring Boot Main 类以及 @SpringBootTest

@SpringBootTest(classes = YourUiSpringBootApp.class)

【讨论】:

    【解决方案2】:

    你不应该在同一个包中有两个 SpringApplication 注解。

    包装一。

    twoapps.one;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication(scanBasePackageClasses = {One.class})
    @EnableAutoConfiguration
    public class One extends SpringApplication {
    }
    

    包装二。

    twoapps.two;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication(scanBasePackageClasses = {Two.class})
    @EnableAutoConfiguration
    public class Two extends SpringApplication {
    
    }
    

    根包和启动器

    package twoapps;
    
    import org.springframework.boot.SpringApplication;
    import twoapps.one.One;
    import twoapps.two.Two;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    public class Application {
    
        public static void main(String[] args) throws Exception {
            new Thread(() -> SpringApplication.run(One.class, args(args, "--spring.profiles.active=one"))).start();
            new Thread(() -> SpringApplication.run(Two.class, args(args, "--spring.profiles.active=two"))).start();
        }
    
        private static String[] args(String[] args, String s) {
            List<String> collect = Arrays.stream(args).collect(Collectors.toList());
            collect.add(s);
            String[] strings = collect.toArray(new String[]{});
            return strings;
        }
    }
    

    这是一个糟糕的主意。请不要这样做。最好有两个不同的项目和一个共同的项目。

    【讨论】:

    • 感谢您的信息。我担心我的方法,但不确定如何处理集成测试。假设公共项目包含 Spring 存储库、需要连接的各种 Spring bean 和一个属性文件(包含 db 连接信息等)我目前使用 @SpringBootApplication@SpringBootTest 来连接和设置以 Spring Boot 特定方式用于我的集成测试的属性。但是,如果我的应用程序不被定义为 SpringBootApplication,我该如何配置它以进行集成测试呢?
    • @James 你可以指定任何东西作为你的 SpringBootApplication 进行测试。重要的是spring扫描的基础包。如果您在包树中有冲突的注释,则上下文将不会启动。 @SpringBootTest(classes = {})。如果您未指定任何类,测试将扫描其包(和子类),否则它将扫描您指定的类的包。
    • 谢谢。我觉得我明白了。因此,普通项目可以拥有自己的 @SpringBootApplication 类,但它应该位于与依赖项目(例如 UI 项目)的 @SpringBootApplication 类不同的包中。话虽如此,UI 项目将需要连接通用项目的组件。正确的?因此,UI 项目的@SpringBootApplication 类需要位于作为所有公共项目类组件的父级的包中,或者指定scanBasePackages 以包含公共项目的基础包。我有这个权利吗?
    • 你的最后一句话是指你的整个帖子吗?就像“上面的设置是一个糟糕的主意,请不要这样做?”或者你是说“用两个类来做,比如我的前两个块引用,而不是像我的最后一个块引用”?
    猜你喜欢
    • 2016-01-22
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 2016-12-22
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 2017-03-08
    相关资源
    最近更新 更多