Spring Dependency injection for interfaces

33,721

Solution 1

You can do it like this:

Interface:

package org.better.place

public interface SuperDuperInterface{
    public void saveWorld();
}

Implementation:

package org.better.place

import org.springframework.stereotype

@Component
public class SuperDuperClass implements SuperDuperInterface{
     public void saveWorld(){
          System.out.println("Done");
     }
}

Client:

package org.better.place

import org.springframework.beans.factory.annotation.Autowire;

public class SuperDuperService{
       @Autowire
       private SuperDuperInterface superDuper;


       public void doIt(){
           superDuper.saveWorld();
       }

}

Now you have your interface defined, written an implementation and marked it as a component - docs here. Now only thing left is to tell spring where to find components so they can be used for autowiring.

<beans ...>

     <context:component-scan base-package="org.better.place"/>

</beans>

Solution 2

You have to specify the type of the class that you want to create object of in your applicationContext.xml file or you can directly annotate that class with any of @Component , @Service or @Repository if you are using latest version of Spring. In web.xml, you have to specify path of xml files as a context-param to servlet, if you are using xml-based configuration.

Share:
33,721
Arturas M
Author by

Arturas M

I'm a technology enthusiast and a Java Software Engineer

Updated on July 12, 2020

Comments

  • Arturas M
    Arturas M almost 4 years

    Well I've been watching some tutorials about Spring dependency injection as well as MVC, but I still seem to not understand how we can instantiate classes specifically?

    I mean if for instance I have a variable

    @Autowired
    ClassA someObject;
    

    How can I make spring create someObject as an Instance of ClassB which would extend ClassA? like someObject = new ClassB();

    I don't really understand how it works in spring, does the ContextLoaderListener do it automatically or do we have to create some kind of configuration class where we specify exactly what spring should instantiate those classes to? (In this case I haven't seen that anywhere in the tutorials) If yes, then how do we specify and how does it look like? And how do we configure it to work in web.xml, etc?

  • Arturas M
    Arturas M over 11 years
    Alright, so i let's say I have to have only ClassB annotated with Component annotation and spring will automatically instantiate a new ClassB() object for me? if Both the ClassA and ClassB would be annotated with Component annotation what would spring then do? Do I understand this correctly?
  • Sumit Desai
    Sumit Desai over 11 years
    If both are annotated with @Component, then while auto-wiring, you will have to use Qualifier annotation which instructs spring to inject that bean which is matching with name you provide with the qualifier.
  • Arturas M
    Arturas M over 11 years
    Thanks, sounds like a really awesome answer, I think I do get it now, I'll try it now. Another question, what if we would need to pass parameters to some constructor? How would it look like or what would we use?
  • sorencito
    sorencito over 11 years
    Also consider using xml descriptors if this is a common case for you.
  • Stefan
    Stefan over 11 years
    You cannot use stereotype Annotations to mark constructor based beans. Either use a default constructor with autowired dependencies or resort to a Java / XML Bases configuration (remove the @Component annotation and the context:component-scan element). See this post here for details: javalobby.org/java/forums/t18396.html
  • user1414745
    user1414745 almost 11 years
    Is someone still reading this thread? My question is - how would you achieve the same without using @Autowired?
  • PavanSandeep
    PavanSandeep over 9 years
    Cool, what if we have multiple implementations ? How would you autowire ? Because you are autowiring at service level right ? I tried to autowire the implementation directly and it fails. Can you explain. Thanks in advance !
  • Triet Doan
    Triet Doan about 6 years
    I have the same question as @PavanSandeep. Does anyone have an answer?
  • JCvanDamme
    JCvanDamme almost 3 years
    @PavanSandeep if you have multiple implementations of an interface, you need to use the @Qualifier annotation (cf. docs.spring.io/spring-framework/docs/current/reference/html/‌​…): Given 2 implementations of an interface, each implementation gets a class level annotation with a unique qualifier, e. g. @Qualifier("interfaceImpl1") for the first implementation and @Qualifier("interfaceImpl2") for the second. A class that declares the interface as a dependency uses the @Qualifier(...) annotation to identify the implementation
  • aurelia
    aurelia over 2 years
    I guess it would be fine to have multiple implementations, as long as only one of them is decorated with @Component? Like, in most cases, you would have your Mock Class, and Regular Class, and you would inject the mock class manually, so no need for decorator there, roght?