我们可以在没有任何Spring实现的情况下自动连接接口吗?

时间:2017-01-06 02:42:23

标签: java spring interface autowired interface-implementation

我们必须与合作伙伴共享我们的代码库,但我们不希望透露某些服务的实现。

假设我们有一个界面FooService及其实现FooServiceImpl

public interface FooService
{
    void doSomething();
}

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

许多其他类自动装配此服务并调用doSomething()。例如:

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

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

如果我只删除FooServiceImpl,当然会在启动时抛出NoSuchBeanException。如果我在FooService自动装配的每个地方都使用@Autowired(required = false),那么只要调用NullPointerException,就会在运行时抛出doSomething()

除了手动删除FooServiceImpl中的每个方法体之外,还有其他方法可以解决这个问题吗?

感谢任何帮助。

3 个答案:

答案 0 :(得分:2)

我同意chrylis;您的用例听起来像是应该发布默认实现。我还将配置您的代码以允许您的库的用户提供他们自己的实现。 Spring允许您使用@Conditional...注释轻松完成此操作。具体来说,我认为你应该使用@ConditionalOnMissingBean

默认实施

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

示例配置

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

当您的合作伙伴使用您的库时,他们会获得默认实现,以及提供更好实现的选项。当您使用库时,您可以创建一个ProprietaryFooServiceImpl bean,它将被注入。

答案 1 :(得分:1)

首先,正如@AdrianShum和@chrylis所评论的那样,FooService的{​​{1}}实现工作正常。因此,“不想透露某些服务的实现”并不清楚你的意思。

  • NoSuchBeanException - 当您在BarServiceImpl.validate()中自动装配FooService时,将进行扫描以查找BarServiceImpl类型的bean。由于您没有FooService的任何实现,因此会发生此错误。
  • NullPointerException - 作为FooService,在初始化期间忽略上述问题。但required=false显然会有private FooService fooService值。因此,当您致电NULL时会发生异常。
  • 现在你可能会想,也许你可以放fooService.doSomething()(或类似的东西) 在@Component上。从Spring文档中,“此注释适用于 要通过classpath自动检测的实现类 扫描“。然后会有 NoSuchBeanException ,因为你没有 实施班。

因此,如果没有在Spring中实现任何实现,则无法自动装配接口。

答案 2 :(得分:0)

  

我们可以在Spring中自动装配一个没有任何实现的接口吗?

您正在尝试为接口 创建实例,这在Java中是不可能的。