simple-robot / simpler-robot

Simple Robot,一个bot风格的Kotlin多平台事件调度框架,异步高效、Java友好!/ A Bot-style Kotlin Multiplatform event scheduling framework, asynchronous and high-performance, java-friendly! 🐱😼😻😸
https://simbot.forte.love
GNU Lesser General Public License v3.0
512 stars 44 forks source link

升级到3.0.0-beta-RC.1项目启动异常 #408

Closed wuyou-123 closed 2 years ago

wuyou-123 commented 2 years ago

版本号

3.0.0-beta-RC.1

附加版本

simbot-component-mirai.version:3.0.0.0-beta-M1

问题描述

升级到3.0.0-beta-RC.1后,启动项目不会加载springboot的组件或者starter,包括database,tomcat,mybatisplus等,升级后也不会执行任何监听器 升级前日志: N1VPLRQ` OO)69FHPMGEE%0 升级后日志: PY@1~FUPL5BTW268HZ7BFOV 上面这个监听器也不会被执行

复现方式

    <simbot.version>3.0.0-beta-RC.1</simbot.version>
    <simbot-component-mirai.version>3.0.0.0-beta-M1</simbot-component-mirai.version>

相关日志

No response

其他补充

No response

ForteScarlet commented 2 years ago

检查自身项目配置、依赖环境等内容是否存在异常。simbot不可能影响到Spring Boot的加载流程,也不应影响到其他的starter或配置的加载。

wuyou-123 commented 2 years ago

找到原因了 当注入EventListenerManager时会导致进程一直阻塞 image 使用applicationContext在启动后getBean才可以继续启动 image

ForteScarlet commented 2 years ago

在正常使用 EventListenerManager 的时候不应会影响启动流程。如下示例:

@SpringBootApplication
@EnableSimbot
class Simbot3SpringbootKtDemoApplication
private val logger = LoggerFactory.getLogger<Simbot3SpringbootKtDemoApplication>()

fun main(args: Array<String>) {
    runApplication<Simbot3SpringbootKtDemoApplication>(*args)
    logger.info("Down.")
}

@Component
class CustomListenerManagerRunner(private val listenerManager: EventListenerManager): CommandLineRunner {
    private val logger = LoggerFactory.getLogger<ListenerManagerConfiguration>()
    override fun run(vararg args: String?) {
        logger.info("listenerManager: {}", listenerManager)
    }
}

检查代码逻辑中是否存在与正常流程不相符的内容。

wuyou-123 commented 2 years ago

又找到原因了 image image image

package com.example.demo

import love.forte.di.annotation.Beans
import love.forte.simboot.annotation.Listener
import love.forte.simboot.spring.autoconfigure.EnableSimbot
import love.forte.simbot.LoggerFactory
import love.forte.simbot.component.mirai.event.MiraiBotStartedEvent
import love.forte.simbot.event.EventListenerManager
import org.springframework.boot.CommandLineRunner
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.stereotype.Component

@EnableSimbot
@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

@Component
class ListenerManager(private val listenerManager: EventListenerManager) : CommandLineRunner {
    private val logger = LoggerFactory.getLogger<ListenerManager>()
    override fun run(vararg args: String?) {
        logger.info("listenerManager: {}", listenerManager)
    }
}

@Beans
class TestListener {
    private val logger = LoggerFactory.getLogger<TestListener>()

    @Listener
    fun MiraiBotStartedEvent.start() {
        logger.info("bot started")
    }
}

只写了这一个类,加了MiraiBotStartedEvent事件并且注入EventListenerManager就会阻塞,只使用任意一个都可以执行后面的(下面的报错是因为我把配置类都删掉了所以连不上数据库)

wuyou-123 commented 2 years ago

顺带一提,在3.0.0-beta-RC.1这个版本中,不知道为什么在注入了EventListenerManager之后可以正常使用aop,不注入EventListenerManager使用aop会报错 在没有注入EventListenerManager时,拿到的listener是cglib代理的对象 image 注入EventListenerManager后,拿到的listener就是EventListenerProxy对象了,这个对象是可以正常使用aop的 image

ForteScarlet commented 2 years ago
@EnableSimbot
@SpringBootApplication
class DemoApplication

fun main(args: Array<String>) {
    runApplication<DemoApplication>(*args)
}

@Component
class ListenerManager(private val listenerManager: EventListenerManager) : CommandLineRunner {
    private val logger = LoggerFactory.getLogger<ListenerManager>()
    override fun run(vararg args: String?) {
        logger.info("listenerManager: {}", listenerManager)
    }
}

@Beans
class TestListener {
    private val logger = LoggerFactory.getLogger<TestListener>()

    @Listener
    fun MiraiBotStartedEvent.start() {
        logger.info("bot started")
    }
}

在目前的 核心库 v3.0.0-beta-RC.2-SNAPSHOT 和 mirai组件 v3.0.0.0-beta-M2-SNAPSHOIT 快照中,上述代码已经不再会发生阻塞。但是对于 Spring Boot Starter 模块的部分实现内容后续可能会被重整,这部分内容可参考或追踪 #413 。