2

我们必须与合作伙伴共享我们的代码库以进行开发,但我们不想透露某些服务的实现。

假设我们有一个接口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();
        ...
    }
}

如果我只是 delete FooServiceImpl,当然NoSuchBeanException会在启动时抛出 a 。如果我在任何地方都使用@Autowired(required = false)FooService 自动装配,那么每当调用NullPointerException时都会在运行时抛出a 。doSomething()

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

任何帮助表示赞赏。

4

4 回答 4

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();
  }
}

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

于 2017-01-06T16:27:00.843 回答
1

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

不。

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

于 2017-01-06T02:58:14.860 回答
1

首先,正如@AdrianShum 和@chrylis 评论的那样,您需要实现FooServiceforBarServiceImpl.validate()才能工作。因此,不清楚您所说的“不想透露某些服务的实现”是什么意思。

  • NoSuchBeanException - 当您自动装配FooServiceBarServiceImpl,将进行扫描以查找FooService类型的 bean。由于您没有任何实现FooService,因此会发生此错误。
  • NullPointerException - 如required=false,上述问题在初始化期间被忽略。但private FooService fooService意志NULL显然是有价值的。因此,当您调用fooService.doSomething().
  • 现在你可能会想,也许你可以把@Component(或类似的东西)放在你的interface. 从 Spring 文档中,“此注释用于通过类路径扫描自动检测实现类”。然后会有NoSuchBeanException,因为你没有实现类。

所以,你不能在没有任何 Spring 实现的情况下自动装配接口。

于 2017-01-06T04:24:33.023 回答
0

在此处输入图片描述嗨,对不起,回答迟了...实际上最近我遇到了这个问题,这实际上是由于多个软件包造成的。这可以通过以下简单点来解决。

  1. 创建 spring 项目时,该项目必须只有一个主包。
  2. 当您需要不同的包时,您需要创建其他包作为主包的子包。
  3. 默认情况下,spring 将在运行时扫描主包。所以如果您创建不同的包,spring 不会将这些包视为主包。
  4. 所以我们必须将所有其他包定义为子包来解决所有这些类型的@Autowired 和 bean 考虑问题......

--->还有任何疑问,请在下面命令...我会关注..

于 2022-02-15T08:44:41.497 回答