2017-01-06 3 views
0

Мы должны поделиться нашей базой кода с партнером для разработки, но мы не хотим раскрывать реализацию некоторых сервисов.Можем ли мы autwire интерфейс без какой-либо реализации весной?

Скажем, у нас есть интерфейс 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 будет выброшено во время запуска. Если я использую @Autowired(required = false) везде, где FooService будет автоматически, NullPointerException будет запущен во время выполнения, когда вызывается doSomething().

Помимо удаления каждого тела метода в FooServiceImpl вручную, есть ли другой способ работать с этим?

Любая помощь приветствуется.

+0

Зачем вы хотите это сделать? Вам нужно «FooService» для «BarServiceImpl», чтобы работать, не так ли? –

+3

Вы должны получить им реализацию * в конце концов *. Лучший случай, который вы могли бы написать для реализации заглушки. Можете взглянуть на обработку данных Datasource Spring Boot, чтобы увидеть, как они предоставляют резервную базу данных в памяти, если вы не настроите реальную. – chrylis

ответ

-1

Можем ли мы autwire интерфейс без какой-либо реализации весной?

No.

Вы пытаетесь создать экземпляр для интерфейса что невозможно в Java.

+0

Почему downvote? Вы можете оставить комментарий –

0

Прежде всего, поскольку комментировали @AdrianShum и @chrylis, вам нужна реализация FooService для работы BarServiceImpl.validate(). Так что неясно, что вы подразумеваете под «, не хотят раскрывать реализацию некоторых услуг».

  • NoSuchBeanException - Как вы в FooService автоматическом связывании BarServiceImpl, сканирование будет сделано, чтобы найти боб FooService типа. Поскольку у вас нет реализации FooService, эта ошибка возникает.
  • NullPointerException - As required=false, выше при запуске игнорируется проблема. Но private FooService fooService будет иметь значение NULL. Таким образом, исключение возникает, когда вы вызываете fooService.doSomething().
  • Теперь вы можете подумать, возможно, вы можете поставить @Component (или аналогичную вещь) на ваш interface. Из документов Spring, «Эта аннотация предназначена для классов реализации, которые должны быть автоматически определены через путь к классам сканирование». Тогда будет NoSuchBeanException, так как у вас нет классов реализации .

Таким образом, вы не можете autwire интерфейс без какой-либо реализации весной.

1

Я согласен с 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, и вместо этого она будет введена.

Смежные вопросы