本文最后更新于 788 天前,其中的信息可能已经有所发展或是发生改变。
最近想搞个QQ机器人,在查询相关资料之后决定选用mirai这个框架,然后在进一步的了解后决定把SpringBoot也弄进去。
优点
- SpringBoot操作数据库更方便
- SpringBoot直接管理Mirai的生命周期
步骤
在spring框架中,是无法在普通类中通过注解注入实例的,因为sping框架在启动的时候,就会将标明交给spring容器管理的类进行实例化,并梳理他们彼此的依赖关系,进行注入,没有交给spring容器管理的普通类,是不会进行注入的,即使你使用了注入的相关注解。
添加实体类
首先在application.yml中添加机器人的账号信息
bot:
number: 1234567898 # QQ账号
password: 12345678 # QQ密码
然后新建QQBot实体类
@Slf4j
@Component
public class QQBot {
@Value("${bot.number}")
private Long number;
@Value("${bot.password}")
private String password;
public void startBot() {
if (number == null || password == null) {
log.error("账号或密码未配置!");
return;
}
Bot bot = BotFactory.INSTANCE.newBot(number, password, new BotConfiguration() {{
setHeartbeatStrategy(HeartbeatStrategy.STAT_HB); // 心跳策略
setProtocol(MiraiProtocol.ANDROID_PHONE); // 登录协议
setCacheDir(new File("data/cache")); // 缓存目录
fileBasedDeviceInfo("data/device.json"); // 设备信息
enableContactCache(); // 列表缓存
}});
bot.login();
}
}
接下来我们需要在程序开始的时候就调用QQBot中的startBot方法,但是因为本小节开始时提到的那个原因,即便我们声明了@Component
,在main中也是不能直接注入的,所以就需要通过上下文间接获得bean。
启动Mirai
方法一. 通过ApplicationContext获取
把main修改成以下内容
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(BotApplication.class,args);
QQBot bot = context.getBean(QQBot.class);
bot.startBot();
}
这个方法就是直接通过run返回的上下文来得到QQBot,比较简单,但是缺点就是如果有其他的普通类想要获得QQBot,就需要把context保存至某个类中,不够优雅。
方法二. 通过ApplicationContextAware获取
Spring容器会自动调用ApplicationContextAware
接口中的setApplicationContext
方法存入上下文环境对象,我们在ApplicationContextAware
的实现类中,就可以通过这个上下文环境对象得到Spring容器中的Bean。
首先创建工具类并实现ApplicationContextAware接口
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(@NotNull ApplicationContext applicationContext) throws BeansException {
if (context == null) {
context = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return context;
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
}
然后修改main
public static void main(String[] args) {
SpringApplication.run(BotApplication.class, args);
QQBot bot = SpringContextUtil.getBean(QQBot.class);
bot.startBot();
}
添加监听
更加详细的说明请移步Mirai官方文档
方法一
直接在QQbot的startBot()最后添加
Listener listener = GlobalEventChannel.INSTANCE.subscribeAlways(GroupMessageEvent.class, event -> {
MessageChain chain = event.getMessage(); // 可获取到消息内容等, 详细查阅 `GroupMessageEvent`
event.getSubject().sendMessage("Hello!"); // 回复消息
})
listener.complete(); // 停止监听
方法二
先创建一个类
public class MyEventHandlers extends SimpleListenerHost {
@Override
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception){
// 处理事件处理时抛出的异常
}
@EventHandler
public void onMessage(@NotNull MessageEvent event) throws Exception { // 可以抛出任何异常, 将在 handleException 处理
event.getSubject().sendMessage("received");
// 无返回值, 表示一直监听事件.
}
@NotNull
@EventHandler
public ListeningStatus onMessage(@NotNull MessageEvent event) throws Exception { // 可以抛出任何异常, 将在 handleException 处理
event.getSubject().sendMessage("received");
return ListeningStatus.LISTENING; // 表示继续监听事件
// return ListeningStatus.STOPPED; // 表示停止监听事件
}
}
然后在QQBot的startBot()最后添加
bot.getEventChannel().registerListenerHost(new MyEventHandlers());