Я реализовал образец шаблона проектирования моста в своем приложении, которое использует загрузку Spring. Мне было интересно, как мне удалось внедрить различные реализации интерфейса. Очевидно, что если я попытаюсь ввести их, он выдаст required a single bean, but 2 were found
. Буду признателен, если вы поможете понять, как этого можно достичь в сочетании с внедрением зависимости:
Цвет. java
package com.example.bridge;
public interface Color {
String fill();
}
Синий. 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";
}
}
Красный. 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";
}
}
Форма. java
package com.example.bridge;
public abstract class Shape {
protected Color color;
public Shape(Color color){
this.color = color;
}
abstract public String draw();
}
Квадрат. 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 static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestBridge {
@Autowired
@Qualifier("Red")
private Red red;
@Test
public void testBridge() {
//a square with red color
Shape square = new Square(red);
assertEquals(square.draw(), "Square drawn. Color is Red");
}
}
ОБНОВЛЕНИЕ:
Во-первых, я заметил, что мне не хватало 'componentScan' для основного класса, и после его добавления теперь запускается приложение. Однако тот же подход не применим к тесту. Получил ли я компонентное сканирование или нет, вот что я получаю:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.bridge.Red' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=Red)}