Код: Выделить всё
@AutowiredЕдинственная зависимость, которую Spring должен автоматически подключать, — это Service.
DTO — это не bean-компонент Spring, и контроллер должен предоставлять его вручную, поэтому я извлекаю команда с:
Код: Выделить всё
beanFactory.getBean(Command.class, inputDto);
Когда я переключаюсь на внедрение конструктора (помечая зависимости как окончательные), Spring больше не может найти соответствующий конструктор, поскольку он пытается автоматически связать оба параметра (включая DTO, который не является bean-компонентом), и это приводит к BeanCreationException.
Код: Выделить всё
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'exampleCommand' defined in file [...\example-project\target\diraliases\OPENSHIFT\classes\com\examplepackage\command\ExampleCommand.class]: Could not resolve matching constructor on bean class [com.examplepackage.command.ExampleCommand] (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities. You should also check the consistency of arguments when mixing indexed and named arguments, especially in case of bean definition inheritance)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:291)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:357)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1613)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1571)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:564)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:393)
at com.examplepackage.controller.ExampleController.exampleApi(ExampleController.java:26)
[...]
Ниже приведены фрагменты кода:
Контроллер:
Код: Выделить всё
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api", produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})
public class ExampleController {
private final BeanFactory beanFactory;
@PostMapping(path = "/exampleApi")
public ResponseEntity exampleApi(@RequestBody String stringDTO) throws Exception {
ExampleCommand command = beanFactory.getBean(ExampleCommand.class, new ExampleDto(stringDTO));
String resource = command.execute();
return ok(resource);
}
}
Код: Выделить всё
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class ExampleCommand {
private final ExampleDto exampleDto;
private final ExampleService exampleService;
public ExampleCommand(ExampleDto exampleDto, ExampleService exampleService) {
this.exampleDto = exampleDto;
this.exampleService = exampleService;
}
public String execute() {return exampleService.exampleMethod(exampleDto);}
}
Код: Выделить всё
@Service
public class ExampleService {
public String exampleMethod(ExampleDto exampleDto) {
return String.join(exampleDto.value(), "-joined");
}
}
Код: Выделить всё
public record ExampleDto(String value) {}
Spring должен использовать конструктор, который принимает служебный компонент + DTO, переданный в getBean(...), не требуя @Autowired для SampleService.
Что происходит на самом деле
Spring не может разрешить конструктор и выдает исключение выше.
Вопрос
Что я делаю не так? Как мне правильно структурировать свой конструктор, чтобы Spring мог внедрить служебный компонент и принять DTO (который не является компонентом) в качестве параметра времени выполнения при использовании beanFactory.getBean(Command.class, dto)?
Нужен ли мне @Autowired для конкретного конструктора или мне следует использовать другой шаблон?
Подробнее здесь: https://stackoverflow.com/questions/798 ... beanfactor
Мобильная версия