Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autowire Spring Bean into interface for default method

I need to add a default method to an interface some classes implement, but my IDE complains (bean may not have been initialized). Code would be something like this:

public interface IValidator {

    MyValidationBean beanToBeAutowired;
    ...
    default Boolean doSomeNewValidations(){
        return beanToBeAutowired.doSomeNewValidations();
    }
}

Is it just that autowiring into interfaces is not allowed or there's something wrong with the code? Using @Component on the interface doesn't make any difference.

I'd rather keep this design instead of using an abstract class.

like image 446
Pablo Fradua Avatar asked Oct 03 '18 07:10

Pablo Fradua


People also ask

Can I use @autowired in interface?

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.

Can interface methods be default?

Interfaces can have default methods with implementation in Java 8 on later. Interfaces can have static methods as well, similar to static methods in classes. Default methods were introduced to provide backward compatibility for old interfaces so that they can have new methods without affecting existing code.

Can we Autowire an interface without the implemented class?

Could we autowire an interface without any implementation in Spring? No. You are trying to create instance for an Interface which is not possible in Java.

Can we Autowire an interface in Spring boot?

@Autowired in Spring Boot. In a Spring Boot application, auto-wiring is enabled by default.


3 Answers

Adding a Variable into interface is not possible in Java. It will be by default a public static final constant. So you have to do either the following:

MyValidationBean beanToBeAutowired = new MyValidationBeanImpl();

or the following:

MyValidationBean beanToBeAutowired();

default Boolean doSomeNewValidations(){
    return beanToBeAutowired().doSomeNewValidations();
}

And you can override the beanToBeAutowired method in the implementation class.

like image 125
shazin Avatar answered Sep 28 '22 10:09

shazin


i can think of solution as below -

public interface IValidator {

   public Service getBeanToBeAutowired();

   default Boolean doSomeNewValidations(){
    return getBeanToBeAutowired().doSomeNewValidations();
   }

}

public class ValidatorClass implements IValidator {

    @Autowire private Service service;

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

}
like image 29
Amit Naik Avatar answered Sep 28 '22 10:09

Amit Naik


Just an idea, send validation bean to interface as parameter;

public interface IValidator {

    default Boolean doSomeNewValidations(MyValidationBean beanToBeAutowired){
        return beanToBeAutowired.doSomeNewValidations();
    }
}

Your callerClass;

public class CallerClass implements IValidator{

    @Autowired
    MyValidationBean beanToBeAutowired;
    ...

    doSomeNewValidations(beanToBeAutowired);

}
like image 38
drowny Avatar answered Sep 28 '22 12:09

drowny