无法使用 Spring Boot 框架区分 Bridge 设计模式中的可注入对象
Posted
技术标签:
【中文标题】无法使用 Spring Boot 框架区分 Bridge 设计模式中的可注入对象【英文标题】:Not able to distinguish injectable objects in the Bridge design pattern with Spring boot framework 【发布时间】:2020-08-11 17:27:24 【问题描述】:我不确定如何在 Spring 的桥接设计模式中注入抽象类及其扩展。让我们考虑一下形状的经典桥梁设计模式示例:
颜色.java
public interface Color
String fill();
Blue.java
@Service("Blue")
public class Blue implements Color
@Override
public String fill()
return "Color is Blue";
Red.java
@Service("Red")
public class Red implements Color
@Override
public String fill()
return "Color is Red";
Shape.java
public abstract class Shape
protected Color color;
@Autowired
private Something something;
@Value($foo.bar)
private String fooBar;
public Shape(Color color)
this.color = color;
abstract public String draw();
Square.java
public class Square extends Shape
public Square(Color color)
super(color);
@Override
public String draw()
return "Square drawn. " + color.fill();
三角形.java
public class Triangle extends Shape
public Triangle(Color color)
super(color);
@Override
public String draw()
return "Triangle drawn. " + color.fill();
BridgeApplication.java
@SpringBootApplication
public class BridgeApplication
public static void main(String[] args)
SpringApplication.run(BridgeApplication.class, args);
控制器:
@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();
当我们想要注入抽象类Shape
或其扩展如Square
或Triangle
时,就会出现问题。由于构造函数接受一个 Color 对象,我们无法确定 Color
是 Red
还是 Blue
(这就是这里使用 Bridge 设计模式的全部意义),所以我们不能定义 Shape
或将其扩展为 Spring Bean,因为将有多个 Color
类型的 bean 可用。简单的解决方法就像我直接构造对象而不是注入它所做的那样。但是,现在对于我要注入的任何值或我想在 Shape
类或其扩展(如 fooBar
或 something
)中注入的任何其他 Bean 将面临所有挑战,因为相应的类是手动构建的。
一种解决方案是开始处理手动注入,这会为 value 和 bean 注入带来很多不必要的复杂性,而且它根本不是一个干净的解决方案。喜欢this 或参考this question。所以我想知道是否有一种干净的方式可以在 Spring 框架中使用某种形式的 Bridge 设计模式,或者由于 Spring 的限制,没有。
【问题讨论】:
【参考方案1】:你可以从ApplicationContext
拿豆子.....但是你需要通过颜色拿豆子....
这是一个例子:
@RestController
public class BridgeController
private final Color red;
private final Shape redSquareShape;
public BridgeController(@Qualifier("Red") Color red,
ApplicationContext applicationContext)
this.red = red;
this.redSquareShape = (Shape) applicationContext.getBean("square", red);
@GetMapping("/red")
@ResponseStatus(HttpStatus.OK)
public String redSquare()
Shape square = new Square(red);
return square.draw();
【讨论】:
我现在需要将 Shape 或 Square 定义为 bean 吗?一旦我将 Shape 定义为 bean,Shape 承包商就会产生歧义。 这里使用颜色构造函数创建形状。您也可以采取方形或三角形。在类型转换中给出它。从 applicationcontext 中,您可以通过传递 bean 名称来获取任何 bean 如果“square”指的是Square类,现在应该怎么做?我们是否也需要一个限定词? 第一个大写是小写字母,其余的都是一样的 我必须实际测试它,但我认为它不会解决整个问题,不过,我需要手动构造“Square”,这会导致注入“Something”时出现一些问题" 和 "fooBar" 因为我们不能为 "Square" 提供 bean以上是关于无法使用 Spring Boot 框架区分 Bridge 设计模式中的可注入对象的主要内容,如果未能解决你的问题,请参考以下文章
spring boot使用profile来区分正式环境配置文件与测试环境配置文件
spring boot使用profile来区分正式环境配置文件与测试环境配置文件