Внедрение зависимостей на основе конструктора не выполняется при запросе bean-компонента через beanFactory.getBean(CommaJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Внедрение зависимостей на основе конструктора не выполняется при запросе bean-компонента через beanFactory.getBean(Comma

Сообщение Anonymous »

Я перехожу с внедрения на местах (

Код: Выделить всё

@Autowired
) для внедрения на основе конструктора в приложение Spring Boot (Java 21), но я сталкиваюсь с BeanCreationException, когда Spring пытается создать экземпляр моего командного объекта.
Мой контроллер получает командный компонент, используя:

Код: Выделить всё

beanFactory.getBean(Command.class, inputDto);
Когда мой класс Command использует внедрение поля, все работает.

Когда я переключаюсь на внедрение конструктора и объявляю зависимости окончательными, Spring не может найти соответствующий конструктор и выдает:

Код: Выделить всё

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'exampleCommand':
Could not resolve matching constructor on bean class [...]
(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities...)
Похоже, что Spring не может решить, какой конструктор использовать, или не может разрешить параметры (параметр DTO является динамическим, служба является компонентом Spring).
Ниже приведены фрагменты кода:
Контроллер:

Код: Выделить всё

@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/api", produces = {MediaType.APPLICATION_JSON_VALUE, "application/hal+json"})
public class PerspectiveController {

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");
}
}
DTO:

Код: Выделить всё

public record ExampleDto(String value) {}
Чего я ожидаю
Spring должен использовать конструктор, который принимает служебный компонент + DTO, переданный в getBean(...), не требуя @Autowired для полей (ExampleService).
Что происходит на самом деле
Spring не может разрешить конструктор и выдает исключение выше.
Вопрос
Что я делаю не так? Как мне правильно структурировать свой конструктор, чтобы Spring мог внедрить служебный компонент и принять DTO в качестве параметра времени выполнения при использовании beanFactory.getBean(Command.class, dto)?

Нужен ли мне @Autowired для конкретного конструктора или мне следует использовать другой шаблон?

Подробнее здесь: https://stackoverflow.com/questions/798 ... beanfactor
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»