Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Dependency injection for interfaces

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?

like image 893
Arturas M Avatar asked Dec 11 '12 06:12

Arturas M


People also ask

Can we inject interface in Spring?

DI exists in two major variants, Constructor-based dependency injection and Setter-based dependency injection. Also see Interface injection is not implemented in Spring clearly states it. So there are only two variants of DI. So if documentation says nothing about interface injection, its clear that its not there.

Can we inject dependency in interface?

interface injection: the dependency provides an injector method that will inject the dependency into any client passed to it. Clients must implement an interface that exposes a setter method that accepts the dependency.

Can interface be injected?

Interface Injection is similar to Getter and Setter DI, the Getter, and Setter DI use default getter and setter but Interface Injection uses support interface a kind of explicit getter and setter which sets the interface property.

Do you need interfaces for dependency injection?

But most often, it's better to introduce an interface to remove the dependency between the client and the service implementation. The injector is the only role that isn't required by the dependency inversion principle. But that's not an issue because you don't need to implement it.


2 Answers

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>
like image 189
Stefan Avatar answered Sep 28 '22 18:09

Stefan


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.

like image 33
Sumit Desai Avatar answered Sep 28 '22 19:09

Sumit Desai