我的项目 A 具有以下规范:
- jar
- Java 7
- Spring 4.2.0 + Spring 安全
- Spring Data JPA、Oracle、H2(带范围测试)
我的项目 B 具有以下规范:
- war
- 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”。我再次运行项目 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)+ Controller (项目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;
}
}
最佳答案
当您将项目 A 作为 Maven 依赖项包含在项目 B 中时,项目 A 中的所有类文件都将在您的类路径中可用。仅此而已。
当您将服务添加为 Autowiring 依赖项时,Spring 容器(项目 B 的)期望实现 bean 在上下文中可用。
spring上下文将无法找到ServiceA的实现,因为它不扫描projectA的包。项目B中@ComponentScan的默认实现只会识别项目B的子包中声明的bean。为了使项目A中的bean在项目B中可用,您需要在项目B的主类中添加显式@ComponentScan,指示spring扫描项目A中的包。
还建议从项目 A 的 pom 文件中删除 Spring 4.X 依赖项
关于java - 添加项目 A (Spring 4.2.x) 作为项目 B (Spring Boot 2、Spring 5) 的依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51849072/