11
votes

Is it possible to have a Spring Bean implement 2 interfaces and be able to autowire that bean using either interface?

I have the following two interfaces:

public interface ServiceA {}

public interface ServiceB {}

Two controllers which use constructor auto-wiring to inject a different service:

@RestController
public class ControllerA {

    public ControllerA(ServiceA service) {}

}

@RestController
public class ControllerB {

    public ControllerB(ServiceB service) {}

}

One class that implements both the services

@Service
public class ServiceImpl implements ServiceA, ServiceB { }

I am getting a NoSuchBeanDefinitionException:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [ServiceB] found for dependency [ServiceB]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

I'm using Spring Boot version 1.4.0

3
I cannot see any @Service or similar in this interfacesSundararaj Govindasamy
which class and which line throws this exception? Actually I wanna know how service beans are injected to your controllers.ali4j

3 Answers

1
votes

You could use the @Qualifier annotation. It can be applied alongside @Autowired or @Inject at the point of injection to specify which bean you want to be injected:

@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert) {
    this.dessert = dessert;
}

Source: Spring in Action 4th edition.

1
votes

Yes it is possible, but it is important, to create the service bean of type ServiceImpl and not as one of the service interfaces :

@Bean
ServiceImpl service() {
    return new Serviceimpl();
}

Spring uses reflection on the declared bean type to find out which interfaces it implements and not on bean.getClass().

Even if this answer was voted dowen, you can be asured : it works . If it does not work for you @scarba05, your problem must be somewhere else...

0
votes

Let me answer your questions one by one:

  1. Yes you can implement more than one interface in any spring bean.
  2. Yes you can autowire with interface too as you did by constructor.

Your shared code working fine just check your SpringBootConfiguration class I think you are not scanning you service package or your service class is not in child package of SpringBootConfiguration class.

That's why you are facing:

NoSuchBeanDefinitionException