【问题标题】:Add Project A (Spring 4.2.x) as dependency of Project B (Spring Boot 2, Spring 5)添加项目 A (Spring 4.2.x) 作为项目 B (Spring Boot 2, Spring 5) 的依赖项
【发布时间】:2018-08-14 20:10:51
【问题描述】:

我的项目 A 具有以下规格:

  • 罐子
  • Java 7
  • Spring 4.2.0 + Spring 安全
  • Spring Data JPA、Oracle、H2(带范围测试)

我的项目 B 具有以下规格:

  • 战争
  • Java 8
  • Tomcat 8.5.x
  • Spring Boot 2
  • Spring 5 + Spring 安全

两个项目都成功构建并单独运行。我希望项目 A 成为项目 B 的依赖项。我正在使用 IntelliJ 并遵循网络上提供的步骤(#1#2),但这是我所做的要点:

文件 -> 项目结构

  • 项目 -> 确保项目 A 的 SDK + 项目级别设置为 Java 8
  • 模块 -> 选择项目 A -> 确保将 SDK + 项目级别设置为 Java 8 以获取源 + 依赖项
  • 模块 -> 单击 + 按钮 > 导入模块 -> 选择项目 A 的 pom.xml -> 遵循导入步骤
  • 模块 -> 选择项目 B -> 确保将 SDK + 项目级别设置为 Java 8 以获取源 + 依赖项
  • 模块 -> 选择项目 A -> 依赖项 -> 单击 + 按钮 > 添加模块依赖项 -> 选择项目 A
  • 将项目 A 作为依赖项添加到项目 B 的 pom.xml 中,并将依赖项的版本与项目 A 的版本匹配(来自 pom)

我成功运行“mvn clean install”。当我在 Tomcat 上运行项目 B 时,我得到:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2018-08-14 15:01:03.796 ERROR 15888 --- [on(3)-127.0.0.1] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

我不确定为什么项目 A 的 JPA/DB 配置会导致项目 B 出现问题,即使项目 A 本身运行良好。但是,经过一番研究,我在我的 SpringBoot 应用程序中添加了以下注释:

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})

这就是我最终得到的结果:

@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class ProjectB extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(ProjectB.class);
    }

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

}

我成功运行“mvn clean install”。我再次运行 Project B,它成功启动了!当我尝试从项目 A 中引用任何东西(即服务)时,它构建得很好,但是在启动时我得到以下信息:

SEVERE [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: 
 org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:167)

    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:754)
***************************
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:730)
APPLICATION FAILED TO START
***************************
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:734)

    at org.apache.catalina.startup.HostConfig.manageApp(HostConfig.java:1736)
Description:
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Parameter 0 of constructor in com.projectB.controller.ControllerName required a bean of type 'com.projecta.service.ServiceName' that could not be found.
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

    at java.lang.reflect.Method.invoke(Method.java:498)

    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:300)
Action:
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819)
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801)

Consider defining a bean of type 'com.projecta.service.ServiceName' in your configuration.

是否可以将 Spring 模块导入 Spring Boot 2?如果是这样,我错过了什么?如果没有,我有什么选择?


编辑1:添加简单服务(项目A)+控制器(项目B)

// Controller in Project B
@RestController
@RequestMapping("/api")
public class SimpleController {
    private SimpleService simpleService;

    @Autowired
    public SimpleController(SimpleService simpleService) {
        this.simpleService = simpleService;
    }

    @GetMapping
    public ResponseEntity<?> generateAndSendEmail() {
        boolean success = simpleService.callSimpleService();
        if (success) {
            return new ResponseEntity<>(OK);
        }
        return new ResponseEntity<>(INTERNAL_SERVER_ERROR);
    }
}

// Service in Project A
@Service
public class SimpleService {
    public boolean callSimpleService() {
        return true;
    }
}

【问题讨论】:

  • 如何在 ProjectB 中配置 ProjectA 的服务?
  • @Compass 由于项目 A 是一个依赖项,我只是这样引用:private ServiceName serviceName;在项目 B 控制器中,IntelliJ 从正确的位置导入它。即使在那之后,我也可以很好地构建项目。启动时出现错误。
  • 如何配置 ServiceName?它是 Autowired 还是有额外的依赖关系需要帮助接线?如果您的 ServiceName 配置不在项目 B 中,它们将无法正确连接。
  • 哦。它是自动接线的
  • 当你自动装配一个需要配置的服务时,你需要定义一个配置服务的@Bean。请提供您的 ServiceName 字段。

标签: java spring spring-boot intellij-idea spring-data-jpa


【解决方案1】:

当您将 projectA 作为 maven 依赖项包含在项目 B 中时,projectA 中的所有类文件都将在您的类路径中可用。仅此而已。

当您将服务添加为自动装配的依赖项时,(项目 B 的)spring 容器期望在上下文中可用的实现 bean。

spring 上下文将无法找到 ServiceA 的实现,因为它不扫描 projectA 的包。 projectB 中 @ComponentScan 的默认实现将仅识别在 Project B 的子包中声明的 beans。要使 Project A 中的 beans 在 Project B 中可用,您需要在 Project B 的主类中添加显式 @ComponentScan 指示 spring 进行扫描项目 A 中的包。

还建议从项目 A 的 pom 文件中删除 Spring 4.X 依赖项

【讨论】:

  • 我也试过@ComponentScan,就像这样:@ComponentScan({"com.projecta","com.probjectb"}),但这并没有解决任何问题。项目 A 也是其他 Spring-only 项目的依赖项。
【解决方案2】:

您是否尝试过手动将服务创建为您的 Spring Boot 应用程序的 bean?在您的主要课程中:

@Bean
public SimpleService simpleService() {
    return new SimpleService();
}

【讨论】:

    猜你喜欢
    • 2019-07-28
    • 2019-08-02
    • 1970-01-01
    • 2019-03-14
    • 2021-07-23
    • 2017-03-19
    • 2020-09-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多