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.
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.