#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, иначе заводской компонент не будет загружен.
Вы можете использовать эти заводские компоненты (они все еще поддерживаются), но у них есть следующие недостатки:
- Они связывают ваш код с spring framework
- Много шаблонов (обычно в типичном приложении могут быть сотни компонентов, поэтому создание заводского компонента для каждого из них является излишеством).
Таким образом, вы можете:
-
Вместо использования заводских компонентов, аннотируйте процессор с помощью
@Component
аннотации (или более специализированной@Service
). -
В качестве альтернативы используйте конфигурацию 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 подойдет просто отлично.