Ошибка в создании бинов
У меня возникла проблема, уже 4 часа ломаю голову, прошу, помогите :(
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainGroupCommands' defined in file
[D:\programming\bot\target\classes\com\bot\commands\MainGroupCommands.class]: Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'mainPrivateCommands' defined in file
[D:\programming\bot\target\classes\com\bot\commands\MainPrivateCommands.class]: Failed to instantiate [com.bot.commands.MainPrivateCommands]: Constructor threw exception
@Data
@AllArgsConstructor
@Service
public class MainPrivateCommands {
private final MyWebhookBot bot = new MyWebhookBot();
private final ProfileService profileService;
// code...
@Data
@AllArgsConstructor
@Service
public class MainGroupCommands {
private final MyWebhookBot bot = new MyWebhookBot();
private final MainPrivateCommands privateCommands;
// code...
Ответы (1 шт):
Проблема для имеющегося кода, представленного в данном вопросе, НЕ воспроизводится.
Оба варианта Lombok-аннотаций @AllArgsConstructor
и @RequiredArgsConstructor
сгенерируют по одному конструктору с одним параметром для инициализации непроинициализированного финального поля:
// MainPrivateCommands
public MainPrivateCommands(ProfileService profileService) {
this.profileService = profileService;
}
// -------
// MainGroupCommands
public MainGroupCommands(MainPrivateCommands privateCommands) {
this.privateCommands = privateCommands;
}
и этого должно оказаться достаточным, чтобы Spring смог выполнить инъекцию через конструктор.
Финальное поле bot
должно успешно проинициализироваться при создании обоих классов.
Однако, если где-то в коде имеются другие варианты конструкторов (например, отличающиеся типами параметров), а Спринг должен вызвать именно тот, что сгенерировал ломбок, то в параметре onConstructor
соответствующей ломбок-аннотации следует указать, чтобы была дополнительно сгенерирована аннотация спринга @Autowired
:
@Data
@AllArgsConstructor(onConstructor = @__(@Autowired))
@Service
public class MainPrivateCommands {
private final MyBot bot = new MyBot();
private final ProfileService profileService;
// ....
}
// ------
@Data
@AllArgsConstructor(onConstructor = @__(@Autowired))
@Service
public class MainGroupCommands {
private final MyBot bot = new MyBot();
private final MainPrivateCommands privateCommands;
}
Также можно явно указать порядок инициализации в конфигурации при помощи аннотации @DependsOn
:
package com.mybot.config;
import com.mybot.commands.MainGroupCommands;
import com.mybot.commands.MainPrivateCommands;
import com.mybot.commands.ProfileService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
@Configuration
public class MyBotConfig {
@Bean
public ProfileService profileService() {
return new ProfileService();
}
@Bean
@DependsOn("profileService")
public MainPrivateCommands mainPrivateCommands() {
return new MainPrivateCommands(profileService());
}
@Bean
@DependsOn("mainPrivateCommands")
public MainGroupCommands mainGroupCommands() {
return new MainGroupCommands(mainPrivateCommands());
}
}