Replies: 1 comment
-
对监听函数的注册可参考 SimbotSpringBootListenerAutoRegisterBuildConfigure.kt,他们会在启动时获取容器中所有的 如果希望在后续动态扫描并加载,可以参考如下代码: @Configuration
public class TestRegisterConfig {
/**
* simbot的Application,用于获取监听函数管理器并动态注册
*/
private final Application application;
/**
* 默认注册的全局参数绑定器。
* 需要注意的是,通过注入是无法获取到任何用户(通过注解)自定义的binder的。
*/
private final List<ParameterBinderFactory> parameterBinderFactory;
/**
* Spring 中的bean工厂
*/
private final ListableBeanFactory listableBeanFactory;
@Autowired
public TestRegisterConfig(Application application, List<ParameterBinderFactory> parameterBinderFactory, ListableBeanFactory listableBeanFactory) {
this.application = application;
this.parameterBinderFactory = parameterBinderFactory;
this.listableBeanFactory = listableBeanFactory;
}
// 此处扫描,并注册
// 具体是怎么触发、怎么执行,根据实际情况变化
public void doRegister() {
// **假设** 这是通过某种方式扫描得到的bean列表
List<Object> beanList = List.of(new SampleListener(), new SampleListener());
// 准备一个监听函数处理器
final var listenerProcessor = new KFunctionListenerProcessor();
// 准备一个bean容器
// bean container 应当能够获取到监听函数自己所属的bean对象,因为需要获取用于执行这个监听函数。
// 如果 bean factory 与自动注入的 factory 不同,需要注意调整
final var beanContainer = new SpringBeanContainer(listableBeanFactory);
// 准备一个BinderManager
final var binderManager = new CoreBinderManager(parameterBinderFactory, Collections.emptyMap());
for (final Object bean : beanList) {
for (final Method method : bean.getClass().getMethods()) {
// 获取到Listener注解。
// 或者用其他什么方式获取也行,比如Spring提供的注解工具类,这样可以支持嵌套注解解析
final var listenerAnnotation = method.getAnnotation(Listener.class);
if (listenerAnnotation == null) {
continue;
}
// 将 method 转化为 KFunction
final var function = ReflectJvmMapping.getKotlinFunction(method);
if (function == null) {
// 并非所有 Java Method 都能转化为 Kotlin function, 次函数可能会得到null
// 考虑处理它,或跳过
throw new NullPointerException("function is null");
}
final var context = new FunctionalListenerProcessContext(function, binderManager, beanContainer);
// 解析为 listener
final var listener = listenerProcessor.process(context);
// 可以考虑再根据获取到的 @Listener 注解扩展信息
// 比如提供优先级信息
// 并构建为 EventListenerRegistrationDescription
// 直接使用 EventListener 也行,但是注解上的部分信息会失效
final var listenerDescription = EventListenerRegistrationDescription.of(listener, listenerAnnotation.priority(), listenerAnnotation.async());
// 注册监听函数
final var handle = application.getEventListenerManager().register(listenerDescription);
// 如果有必要,可以选择保存handle用于以后卸载这个监听函数,或者忽略它。
}
}
}
}
@Component
class SampleListener {
@Listener
public void listener() {
// do ...
}
}
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
涉及的编程语言
Java
涉及的组件库
mirai (QQ)
疑问描述
请问一下,如果我springboot要接入外部的bean,我现在需要扫描外部bean的listener方法,我应该如何注册到simbot里面,让事件分发器进行分发,我现在是自己在主程序写了一个监听器方法自己实现的分发,但是我能力有限写不了那么好,希望直接从底层扫描到分发器里面
Beta Was this translation helpful? Give feedback.
All reactions