简体   繁体   中英

Spring autowire the only implementation without defining the bean

I have the following case:

@Service
interface OrderingService {

}

public class DefaultOrderingService implements OrderingService {

}

@RestController
public class DefaultOrderingRestController {
    private final OrderingService orderingService;
    public DefaultOrderingRestController(OrderingService orderingService) {
        this.orderingService = orderingService;
    }
}

and I would like that Spring autowires the only implementation to the interface by scanning the code. Is this possible?

In other words, currently there are 2 solutions to this issue and I'm asking if there's a third:

  1. Move the @Service declaration from the interface OrderingService to the implementation DefaultOrderingService
  2. In the Configuration, define the specific Bean as follows:
 @Configuration 
 public class DefaultConfig {
      @Bean
      public OrderingService orderingService() {
          return new DefaultOrderingService();
      }
 }

QUESTION: Is it possible to have Spring automagically scan (then Spring finds only one implementation of OrderingService) and autowire? If yes, how to do it? If not, is it not a good practice and why?

i don't know if that posibble or not, but I have a diffirent approach that could be help:

Add configiration file to hold type of your bean, lets say there are two implementation of OrderingService one is FAKE and DEFAULT in order to have one only in runtime, you have to declare both of beans in project context like below:

@Bean
OrderingService fakeOrderingService() {
  return new FakeOrderingService();
}

@Bean
OrderingService defaultOrderingService() {
  return new DefaultOrderingService();
}

If you want one of them, you have to add ConditionalOnProperty like below:

@Bean
@ConditionalOnProperty("app.config.type", havingValue = "FAKE")
OrderingService fakeOrderingService()..

@Bean
@ConditionalOnProperty("app.config.type", havingValue = "DEFAULT", matchIfMissing = true)
OrderingService defaultOrderingService()...

matchIfMissing = true that will help, if the configuration does not added in your environment, So spring will autowire defaultOrderingService in case property missing or if property value is DEFAULT , and fakeOrderingService if property value is FAKE

I hope that will help

The problem with your third solution is that it is dependent on the implementation of the interface. If no corresponding implementation is found, spring would give an error. So i suppose it is definitely not a good practice. Also spring @service annotation is not inherited. However if you still want to have any alternate solution. You could prefer to define separate beans for the each of the implementation and use a qualifier to get bean from the application context.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM