In normal Spring, when we want to autowire an interface, we define it's implementation in Spring context file.
currently we only autowire classes that are not interfaces.
Another part of this question is about using a class in a Junit class inside a Spring boot project.
If we want to use a CalendarUtil for example, if we autowire CalendarUtil, it will throw a null pointer exception. What can we do in this case? I just initialized using "new" for now...
Dependency Injection has eased developer's life. Earlier, we use to write factory methods to get objects of services and repositories. Now With help of Spring boot and Autowired annotation, we can inject dependency in any classes easily.
If you try to use @Autowired on an interface, the Spring framework would throw an exception as it won't be able to decide which implementation class to use.
So, you can't autowire an interface without any implementation in Spring.
You autowire the interface so you can wire in a different implementation--that's one of the points of coding to the interface, not the class.
Use @Qualifier
annotation is used to differentiate beans of the same interface
Take look at Spring Boot documentation
Also, to inject all beans of the same interface, just autowire List
of interface
(The same way in Spring / Spring Boot / SpringBootTest)
Example below:
@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); } } }
For the second part of your question, take look at this useful answers first / second
You can also make it work by giving it the name of the implementation.
Eg:
@Autowired MyService firstService; @Autowired MyService secondService;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With