【发布时间】:2019-06-15 09:50:25
【问题描述】:
我正在尝试在具有多个 Maven 模块的 Spring Boot 应用程序上实现 Hexagonal 架构。主要思想依赖于抽象,而不是具体。
我创建了三个模块test-core、test-adapter、test-application,基本上如here所述:
┌ \ pom.xml
├ \ test-core
│ ├ pom.xml
│ └─ src\com\example\core\
| ├─ ConfigCore.java
| └─ FooService.java
├ \ test-adapter
│ ├ pom.xml
| └─ src\com\example\adapter\
| ├─ ConfigAdapter.java
| └─ FooServiceImpl.java
└ \ test-application
├ pom.xml
└─ src\com\example\
├─ ConfigApplication.java
└─ Application.java
主要思想是有下一个依赖:
- test-adapter 依赖于 test-core
- test-application 依赖于 test-core
仅此而已。但是,如果 test-application 依赖于 test-adapter,则无法在没有第三个依赖项的情况下实现。在给定的示例中,我使用了它们以这种方式进行操作(添加了直接依赖项)。但是我想避免这种情况,因为我想在没有这种耦合的情况下进行架构设计。 是否有可能以某种方式实施?还是我想要的太多?或者我错误地理解了端口和适配器架构?
为了使问题更清楚,您可以在下面找到代码。 FooServices.java
package com.example.core;
public interface FooService { String execute(); }
FooServiceImpl.java
package com.example.adapter;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Qualifier;
import com.example.core.FooService;
@Service
@Qualifier("fooService")
public class FooServiceImpl implements FooService {
public String execute() { return "Hello world!"; }
}
Application.java
package com.example;
@SpringBootApplication(scanBasePackages = {"com.example"})
public class Application {
@Autowired
@Qualifier("fooService")
FooService fooService;
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) { return args -> { System.out.println(fooService.execute()); }; }
}
在 \test-application\pom.xml 中没有对 test-adapter 的书面依赖
<dependency>
<groupId>com.example</groupId>
<artifactId>test-adapter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
我不断收到下一个错误
在上下文初始化期间遇到异常 - 取消刷新尝试:org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为“应用程序”的bean时出错:通过字段“fooService”表示不满足的依赖关系;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的“com.example.core.FooService”类型的合格 bean:预计至少有 1 个有资格作为自动装配候选者的 bean。依赖注解:{@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=fooService)}
如您所见,@Qualifier 注释在这里没有帮助。 @ComponentScan(basePackages = {"com.example"})、@SpringBootApplication(scanBasePackages = {"com.example"}) 也是如此。
解决方案是实施后续步骤: ConfigCore.java
package com.example.core;
@Configuration
@ComponentScan(basePackages = {"com.example.core"})
public class ConfigCore { }
ConfigAdapter.java
package com.example.adapter;
@Configuration
@ComponentScan(basePackages = {"com.example.adapter"})
public class ConfigAdapter { }
ConfigApplication.java
package com.example;
import com.example.core.ConfigCore;
import com.example.adapter.ConfigAdapter;
@Configuration
@ComponentScan(basePackages = {"com.example"})
@Import({ConfigCore.class, ConfigAdapter.class})
public class ConfigApplication { }
并把对应的依赖(上面提到的)放到pom.xml中。在这种情况下,一切正常。但是,正如我提到的,我认为这不是正确的方法。您能否帮助我了解消除 test-adapter 和 test-application 之间这种依赖关系的可能性?
【问题讨论】:
-
避免不必要的具体,例如使用
Qualifier,除非您有已知的冲突需要管理。 -
您是否尝试使用
<scope>runtime</scope>而不是<scope>compile</scope>?这应该有效。运行 Claspath 时验证test-adapter类是否可用。 -
@chrylis,当然,@Qualifier 是可以提出这种方法的唯一示例。 @Neo,我不太确定,我明白你的意思。它与
<scope>compile</scope>一起使用没有问题。我的想法是根本没有这种依赖,它的范围无关紧要。你认为摆脱这种关系是不可能的吗?
标签: java spring maven architecture microservices