29

Java 8 added a new feature by which we can provide method implementation in interfaces. Is there any way in Spring 4 by which we can inject beans in the interface which can be used inside the method body? Below is the sample code

public interface TestWiring{

@Autowired
public Service service;// this is not possible as it would be static.
//Is there any way I can inject any service bean which can be used inside testWiringMethod.
default void testWiringMethod(){
  // Call method of service
  service.testService();
 }
}
Ashish Shukla
  • 417
  • 1
  • 4
  • 12
  • 4
    You can't instantiate an interface. How would you autowire a field in it? – Tunaki Oct 15 '15 at 12:37
  • I want to use spring managed services inside my method body. One way is to use ApplicationContext.getbean(") method. But I am looking for any feature in Spring 4 which I can leverage for injecting Spring managed beans in interface. Interface would be implemented by some bean. So it should be available in the implementing class. By default since members of interface are static final so I can not use @autowiring directly. – Ashish Shukla Oct 15 '15 at 12:45
  • DI in Spring works either by setting the dependencies in the constructor (constructor injection), or via property (setter injection). In an interface, you do not have a constructor, nor instance variables (the variables you declare in an interface are `static final`), so there is no way to inject anything. – Ruben Oct 15 '15 at 14:11
  • Cant you use abstract class for this ? – Niraj Sonawane Dec 21 '18 at 11:12
  • 1
    A possible use case can be in Spring Data interfaces which implement CRUD Repository. I am testing the new Spring R2DBC with Mysql. So like usual Spring Data Interfaces, there is no way to write custom abstract methods like findByIdLike and other custom queries without providing the implementation. In this case, I need to use the Database client and write the custom method with the implementaton, maybe using the new Java 8 default methods. I don't want to write a new Interface and implementation class since both Spring and my interface would be interacting with the same Entity/Table. – Mohammed Salman Shaikh Apr 19 '20 at 16:49
  • in a default method you can provide code, so the question is perfectly posed – Andrea Scarafoni Jul 12 '22 at 08:07

2 Answers2

43

This is a bit tricky but it works if you need the dependency inside the interface for whatever requirement.

The idea would be to declare a method that will force the implemented class to provide that dependency you want to autowire.

The bad side of this approach is that if you want to provide too many dependencies the code won't be pretty since you will need one getter for each dependency.

public interface TestWiring {

   public Service getService();

   default void testWiringMethod(){
       getService().testService();
   }

}


public class TestClass implements TestWiring {

    @Autowire private Service service;

    @Override
    public Service getService() {
        return service;
    }

}
ibai
  • 1,143
  • 1
  • 17
  • 28
4

You can created Class utils of application context and use it everywhere even not bean class .

you can have code somethins this :

public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) {
        ApplicationContextUtil.applicationContext = context;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

}

and add this to your spring configuration

<bean class="com.example.ApplicationContextUtil" id="applicationContextUtil"/>

now simple to use when you need :

ApplicationContextUtil.getApplicationContext().getBean(SampleBean.class)

this word in web and simple spring app.

Mohsen
  • 438
  • 5
  • 14