web-dev-qa-db-ja.com

複数の実装を持つインターフェースを自動配線するスプリングブート

通常のSpringでは、インターフェイスを自動配線する場合、Springコンテキストファイルで実装を定義します。 Spring bootはどうですか?どうすればこれを達成できますか?現在、インターフェイスではないクラスのみを自動配線します。この質問の別の部分は、Springブートプロジェクト内のJunitクラスでクラスを使用することです。たとえば、CalendarUtilを使用する場合、CalendarUtilを自動配線すると、nullポインタ例外がスローされます。この場合、何ができますか?今のところ「new」を使用して初期化したばかりです...

8
user666

つかいます @Qualifier注釈は、同じインターフェースのBeanを区別するために使用されます
Spring Bootをご覧ください ドキュメント
また、同じインターフェースのすべてのBeanを注入するには、ちょうどautowireListインターフェースの
(Spring/Spring Boot/SpringBootTestでも同じです)
以下の例:

@SpringBootApplication
public class DemoApplication {

public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
}

public interface MyService {

    void doWork();

}

@Service
@Qualifier("firstService")
public static class FirstServiceImpl implements MyService {

    @Override
    public void doWork() {
        System.out.println("firstService work");
    }

}

@Service
@Qualifier("secondService")
public static class SecondServiceImpl implements MyService {

    @Override
    public void doWork() {
        System.out.println("secondService work");
    }

}

@Component
public static class FirstManager {

    private final MyService myService;

    @Autowired // inject FirstServiceImpl
    public FirstManager(@Qualifier("firstService") MyService myService) {
        this.myService = myService;
    }

    @PostConstruct
    public void startWork() {
        System.out.println("firstManager start work");
        myService.doWork();
    }

}

@Component
public static class SecondManager {

    private final List<MyService> myServices;

    @Autowired // inject MyService all implementations
    public SecondManager(List<MyService> myServices) {
        this.myServices = myServices;
    }

    @PostConstruct
    public void startWork() {
        System.out.println("secondManager start work");
        myServices.forEach(MyService::doWork);
    }

}

}

質問の2番目の部分については、この便利な回答をご覧ください first / second

16
tsarenkotxt

また、実装の名前を指定することで機能させることもできます。

例えば:

@Autowired
MyService firstService;

@Autowired
MyService secondService;
9
Raj Shah

コメントで述べたように、@Qualifier注釈、 docs で説明されているように、異なる実装を区別できます。

テストには、同じこともできます。例えば:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class MyClassTests {

        @Autowired
        private MyClass testClass;
        @MockBean
        @Qualifier("default")
        private MyImplementation defaultImpl;

        @Test
        public void givenMultipleImpl_whenAutowiring_thenReturnDefaultImpl() {
    // your test here....
    }
}
2
Urosh T.