Could we autowire an interface without any implementation in Spring?

11.6k views Asked by At

We have to share our code base with a partner for developing, but we don't want to reveal the implementation of some services.

Say we have an interface FooService and its implementation FooServiceImpl.

public interface FooService
{
    void doSomething();
}

@Service
public class FooServiceImpl implements FooService
{
    @Override
    public String doSomething();
    {
        ...
    }
}

Many other classes autowire this service in and call doSomething(). For example:

@Service
public class BarServiceImpl implements BarService
{
    @Autowired
    private FooService  fooService;

    @Override
    public String validate();
    {
        fooService.doSomething();
        ...
    }
}

If I just delete FooServiceImpl, of course a NoSuchBeanException will be thrown while starting. If I use @Autowired(required = false) everywhere that FooService is autowired, a NullPointerException will be thrown at runtime whenever doSomething() gets called.

Besides the removal of each method body in FooServiceImpl manually, is there any other way to work this around?

Any help is appreciated.

4

There are 4 answers

0
Ramanujan R On

First of all, as @AdrianShum and @chrylis commented, you need an implementation of FooService for BarServiceImpl.validate() to work. So it's not clear what you mean by "don't want to reveal the implementation of some services".

  • NoSuchBeanException - As you are autowiring FooService in BarServiceImpl, scanning will be done to find a bean of FooService type. As you don't have any implementation of FooService, this error occurs.
  • NullPointerException - As required=false, above problem is neglected during initialization. But the private FooService fooService will have a NULL value obviously. So exception occurs when you call fooService.doSomething().
  • Now you may think, may be you can put @Component (or similar thing) on your interface. From the Spring docs, "This annotation is for the implementation classes to be autodetected through classpath scanning". Then there will be NoSuchBeanException, as you have no implementation classes.

So, you can't autowire an interface without any implementation in Spring.

0
Sundararaj Govindasamy On

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.

1
RustyTheBoyRobot On

I agree with chrylis; your use case sounds like you should ship a default implementation. I would also configure your code to allow the users of your library to provide their own implementation. Spring lets you do this easily with their @Conditional... annotations. Specifically, I think you should use @ConditionalOnMissingBean.

Default implementation

@Component
public class DefaultFooServiceImpl implements FooService {
  @Override
  public void doSomething() {
    LOG.info("Using default implementation of doSomething(); nothing will happen");
  }
}

Sample configuration

@Configuration
public class ServiceConfig {
  @ConditionalOnMissingBean(FooService.class)
  @Bean
  DefaultFooServiceImpl defaultFooServiceImpl() {
    return new DefaultFooServiceImpl();
  }
}

When your partner uses your library, they get the default implementation, as well as the option to provide a better implementation. When you use your library, you can create a ProprietaryFooServiceImpl bean and it will get injected instead.

0
Santil On

enter image description hereHi Sorry For Late answer... Actually recently I have faced this issue, this is actually due to the multiple packages. This can be solved by the below simple points.

  1. When you create an spring project, the project must be with only one main package.
  2. When you need different packages you need to create the other packages as the sub-packages of the main package.
  3. As default the spring will scan the main package in the runtime.. So id you create different packages spring won't consider the packages as the main package.
  4. So we have to define all other packages as the sub-package to solve all these types of @Autowired and bean consideration issues...

---> Still Any doubts please command below...I will be following..