有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JavaSpring注入两种接口实现以使用桥接设计模式

我在使用Spring boot的应用程序中实现了一个桥接设计模式示例。我想知道我如何能够设法注入接口的不同实现。显然,如果我尝试注入它们,它会抛出required a single bean, but 2 were found。如果您能帮助理解如何结合依赖注入来实现这一点,我将不胜感激:

颜色。爪哇

package com.example.bridge;

public interface Color {

  String fill();
}

蓝色。爪哇

package com.example.bridge;

import org.springframework.stereotype.Service;

@Service("Blue")
public class Blue implements Color {
  @Override
  public String fill() {
    return "Color is Blue";
  }
}

红色。爪哇

package com.example.bridge;

import org.springframework.stereotype.Service;

@Service("Red")
public class Red implements Color {
  @Override
  public String fill() {
    return "Color is Red";
  }
}

形状。爪哇

package com.example.bridge;

public abstract class Shape {
  protected Color color;

  public Shape(Color color){
    this.color = color;
  }

  abstract public String draw();
}

正方形。爪哇

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();
  }
}

三角形。爪哇

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();
  }
}

Bridge应用程序。爪哇

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)}

共 (2) 个答案

  1. # 1 楼答案

    @Qualifier是解决方案。用`@限定符(“唯一名称”)标记component,在注入bean时,使用此限定符

    @Service("blue")
    public class Blue implements Color {
        @Override
        public String fill() {
            return "Color is Blue";
        }
    }
    
    @Service("red")
    public class Red implements Color {
        @Override
        public String fill() {
            return "Color is Red";
        }
    }
    

    自动布线时,可以执行以下操作:

    @Autowired
    @Qualifier("red")
    private Color red;
    

    编辑


    执行构造函数注入时,请执行以下操作:
    @Autowired
    public SomeClassConstructor(@Qualifier("red") Color red) {
        ...
    }
    
  2. # 2 楼答案

    您可以尝试在服务中使用@Qualifier注释。 然后在@Autowired中,必须使用相同的注释引用它们

    https://docs.spring.io/spring/docs/4.3.12.RELEASE/spring-framework-reference/htmlsingle/#beans-autowired-annotation-qualifiers

    @Service
    @Qualifier("firstImplementation")
    public class fistImplementation extends MyInterface {
     //doSomething
    }
    
    @Service
    @Qualifier("secondImplementation")
    public class secondImplementation extends MyInterface  { 
    //doSomething
    }
    
    
    @Autowired
    @Qualifier("firstImplementation") 
    MyInterface myInterface;