Класс на основе заводского класса недоступен для автоматической проводки

#java #spring

#java #spring

Вопрос:

Я пытаюсь изучить основы Spring и определил этот класс?

 public class Processor {

    public Processor() {
        this.setup();
    }

    private void setup(){
       //run some setup code
    }

    public String processString(String str) {
        // process the string
        return str;
    }

}
  

Я хочу включить этот класс, поэтому я использую factory bean:

Чтение https://www.baeldung.com/spring-factorybean Я использую:

 public class Processor implements FactoryBean<Processor> {

    @Override
    public Processor getObject() throws Exception {
        return new Processor();
    }

    @Override
    public Class<?> getObjectType() {
        return Processor.class;
    }
}
  

Для тестирования:

 @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ProcessorFactory.class)
public class ProcessorTest {

    @Autowired
    private Processor processor;

        @Test
    public void testProcessor() {
            //Some tests
        }
}
  

Это работает так, как ожидалось.

Когда я пытаюсь использовать

 @Autowired
private Processor processor;
  

в другом месте моего проекта я получаю ошибку времени компиляции :

 Could not autowire. No beans of 'Processor' type found.
  

Я неправильно настроил завод? Я должен аннотировать объект процессора, чтобы указать, что он должен быть автоматически подключен? Возможно, это недопустимый вариант использования для Factory ?

Комментарии:

1. Пожалуйста, попробуйте изменить универсального типа в «открытый класс<?> getObjectType()» с процессором вместо ?

Ответ №1:

В целом, factory beans довольно устарели, первые версии spring действительно использовали этот подход, но spring с тех пор эволюционировал.

Сам компонент Factory должен быть зарегистрирован в конфигурации spring (самые первые версии spring использовали конфигурацию на основе xml, поскольку аннотации Java в то время не существовали), поэтому в руководстве содержится пример конфигурации XML. В любом случае, это, вероятно, причина сбоя. В тесте вы также должны указать путь к конфигурации xml, иначе заводской компонент не будет загружен.

Вы можете использовать эти заводские компоненты (они все еще поддерживаются), но у них есть следующие недостатки:

  1. Они связывают ваш код с spring framework
  2. Много шаблонов (обычно в типичном приложении могут быть сотни компонентов, поэтому создание заводского компонента для каждого из них является излишеством).

Таким образом, вы можете:

  1. Вместо использования заводских компонентов, аннотируйте процессор с помощью @Component аннотации (или более специализированной @Service ).

  2. В качестве альтернативы используйте конфигурацию Java:

 
@Configration
public class MyConfig {
  
  @Bean
  public Processor processor() {
      // optionally slightly customize the creation of the class if required;
      return new Processor();
  }
}
  

Комментарии:

1. использование @Bean гарантирует, что будет создан только один экземпляр этого класса?

2. В обоих случаях (@Component и @Bean подход) будет только один компонент — его область по умолчанию (называемая singleton в spring). В отличие от этого, вы можете настроить его как прототип области видимости, чтобы при необходимости был создан новый экземпляр): @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) (см. baeldung.com/spring-bean-scopes )

3. Компонента, кажется, достаточно. Я не уверен, зачем использовать конфигурацию с Bean и создавать новый класс MyConfig. Просто аннотируйте процессор компонентом, и класс автоматически подключается. Допустимо ли использование компонента вместо конфигурации с помощью компонента?

4. Да, это два разных способа, оба будут работать — просмотрите один из них, а не оба. @Component доступен с весны 2.5 @Configuration , начиная с весны 3.0. В целом подход к настройке Java может быть более гибким, но он довольно продвинутый, в основном, если вы пишете библиотеки на основе Spring для общего использования. Для простого применения / обучения подход @Component подойдет просто отлично.