构造函数注入以及 JDA 和 Spring 启动

Constructor Injection together with JDA and Spring Boot

我正在努力初始化 JDA,因为“addEventListeners”需要我输入 EventListeners。但是,我的 EventListeners 有“注入的构造函数”(如果这是正确的词)正在抓住我的 Dao。

我很乐意在我的 EventListener 中使用 @Autowire,但它一直给我一个 NullPointer。

我认为问题是 JDA 扩展了他们的 EventListener,它基本上在 Spring Boot 之外加载,即使我已经在 Listener 上添加了 @Service 注释。

您可以在下面查看我的问题: .addEventListeners(新的 JDAEventListener())

显然,我无法做到 new JDAEventListener(),因为它需要 WixSubscriptionDao。但是,我无法理解如何在没有 WixSubscriptionDao 的情况下启动 JDAEventListener,因为我需要 Dao 来进行进一步的数据处理。

public static void main(String[] args) throws InterruptedException, LoginException {

    JDA jda = JDABuilder.createDefault("XXXXXXXXXXXXXXXXXXXXXX")
            .enableIntents(GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS)
            .setChunkingFilter(ChunkingFilter.ALL)
            .setMemberCachePolicy(MemberCachePolicy.ALL)
            .addEventListeners(new JDAEventListener())
            .build();
    DISCORD_CONSTANT.jda = jda.awaitReady();
    setupDefault();
}
@Service
public class JDAEventListener implements EventListener {

    private final WixSubscriptionDao wixSubscriptionDao;

    public JDAEventListener(WixSubscriptionDao wixSubscriptionDao) {
        this.wixSubscriptionDao = wixSubscriptionDao;
    }

    @Override
    public void onEvent(@NotNull GenericEvent genericEvent) {
        if (genericEvent instanceof ReadyEvent) {
            System.out.println("ReadyEvent done");
            ArrayList<WixSubscription> wixSubscriptions = wixSubscriptionDao.findAll();
            System.out.println(wixSubscriptions.size());
    }
}

我很想这样做,但正如上面所写,@Autowired Dao 给了我一个 NullPointer,即使它是在 SpringConfig 中定义的。 (DAO 在使用构造方法时完美运行)

@Service
public class JDAEventListener implements EventListener {

    @Autowired
    private WixSubscriptionDao wixSubscriptionDao;

    public JDAEventListener() {
    }

    @Override
    public void onEvent(@NotNull GenericEvent genericEvent) {
        if (genericEvent instanceof ReadyEvent) {
            System.out.println("ReadyEvent done");
            ArrayList<WixSubscription> wixSubscriptions = wixSubscriptionDao.findAll();
            System.out.println(wixSubscriptions.size());
        }
}

我建议您创建带有 @Component 注释的 class,它实现了 CommandLineRunner 接口。这意味着,run 方法将在应用程序启动时执行。此外,您可以将其他 Spring beans 注入其中,例如 JDAEventListener beans.

@Component
public class JDAInitializer implements CommandLineRunner {
    private final JDAEventListener jdaEventListener;
    
    // Constructor injection
    public JDAInitializer(JDAEventListener jdaEventListener) {
        this.jdaEventListener = jdaEventListener;
    }

    @Override
    public void run(String... args) throws Exception {
        JDA jda = JDABuilder.createDefault("XXXXXXXXXXXXXXXXXXXXXX")
                .enableIntents(GatewayIntent.GUILD_MESSAGES, GatewayIntent.GUILD_MEMBERS)
                .setChunkingFilter(ChunkingFilter.ALL)
                .setMemberCachePolicy(MemberCachePolicy.ALL)
                .addEventListeners(jdaEventListener)
                .build();
        DISCORD_CONSTANT.jda = jda.awaitReady();
        setupDefault();
    }

 ...
}