【发布时间】:2020-04-14 10:58:56
【问题描述】:
我注意到在 Spring boot 中使用 Bridge 设计模式的例子有些奇怪。为了克服在类路径中有两个相同类型的 bean 的问题,我使用了 Qualifier 注释。但是,由于某种原因,如果不使用通配符进行组件扫描,它就无法工作。
颜色.java
package com.example.bridge;
public interface Color {
String fill();
}
Blue.java
package com.example.bridge;
import org.springframework.stereotype.Service;
@Service("Blue")
public class Blue implements Color {
@Override
public String fill() {
return "Color is Blue";
}
}
Red.java
package com.example.bridge;
import org.springframework.stereotype.Service;
@Service("Red")
public class Red implements Color {
@Override
public String fill() {
return "Color is Red";
}
}
Shape.java
package com.example.bridge;
public abstract class Shape {
protected Color color;
public Shape(Color color){
this.color = color;
}
abstract public String draw();
}
Square.java
package com.example.bridge;
import org.springframework.stereotype.Service;
@Service
public class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public String draw() {
return "Square drawn. " + color.fill();
}
}
三角形.java
package com.example.bridge;
@Service
public class Triangle extends Shape {
public Triangle(Color color) {
super(color);
}
@Override
public String draw() {
return "Triangle drawn. " + color.fill();
}
}
BridgeApplication.java
package com.example.bridge;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan("com.example.bridge")
public class BridgeApplication {
public static void main(String[] args) {
SpringApplication.run(BridgeApplication.class, args);
}
}
控制器:
package com.example.bridge;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BridgeController {
@Autowired
@Qualifier("Red")
private Color red;
@GetMapping("/red")
@ResponseStatus(HttpStatus.OK)
public String redSquare() {
Shape square = new Square(red);
return square.draw();
}
}
此项目启动失败,出现以下异常:
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-04-14 20:52:52.839 ERROR 9689 --- [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.bridge.Square required a single bean, but 2 were found:
- Blue: defined in file [IdeaProjects/test-bridge-design/target/classes/com/example/bridge/Blue.class]
- Red: defined in file [IdeaProjects/test-bridge-design/target/classes/com/example/bridge/Red.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
好的,现在让我们将组件扫描的基本包更改为使用"com.example.*"。同样的问题。
现在,如果我将基本包更改为"com.example.bridge.*",它可以工作并且可以启动应用程序。从技术上讲,我不需要为基本包设置通配符,它应该递归地获取所有 bean。另外,我不明白"com.example.bridge.*" 和"com.example.*" 之间的区别是什么。
【问题讨论】:
-
您说它有效...但是
Square中注入了哪种颜色?我在您的代码中没有看到任何主要或限定符... -
@CodeScale 我已经添加了控制器部分。在这种情况下,它会按预期返回红色方块。
-
我不明白你为什么将
Square定义为spring bean et init这个类型在控制器中手动Shape square = new Square(red);这样Square不需要是spring bean...
标签: java spring spring-boot dependency-injection