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
-
涉及的编程语言
Java
涉及的组件库
mirai (QQ)
疑问描述
请问一下,如果我springboot要接入外部的bean,我现在需要扫描外部bean的listener方法,我应该如何注册到simbot里面,让事件分发器进行分发,我现在是自己在主程序写了一个监听器方法自己实现的分发,但是我能力有限写不了那么好,希望直接从底层扫描到分发器里面
Beta Was this translation helpful? Give feedback.
All reactions