探索 Sa-Token 模块重新出发
?官网的东西这里就不讲了,直接从源码出发。
/*
* Copyright 2020-2099 sa-token.cc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.dev33.satoken.listener;
import java.util.ArrayList;
import java.util.List;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.error.SaErrorCode;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.StpLogic;
/**
* Sa-Token 事件中心 事件发布器
*
* <p> 提供侦听器注册、事件发布能力 </p>
*
* @author click33
* @since 1.31.0
*/
public class SaTokenEventCenter {
// --------- 注册侦听器
private static List<SaTokenListener> listenerList = new ArrayList<>();
static {
// 默认添加控制台日志侦听器
listenerList.add(new SaTokenListenerForLog());
}
/**
* 获取已注册的所有侦听器
* @return /
*/
public static List<SaTokenListener> getListenerList() {
return listenerList;
}
/**
* 重置侦听器集合
* @param listenerList /
*/
public static void setListenerList(List<SaTokenListener> listenerList) {
if(listenerList == null) {
throw new SaTokenException("重置的侦听器集合不可以为空").setCode(SaErrorCode.CODE_10031);
}
SaTokenEventCenter.listenerList = listenerList;
}
/**
* 注册一个侦听器
* @param listener /
*/
public static void registerListener(SaTokenListener listener) {
if(listener == null) {
throw new SaTokenException("注册的侦听器不可以为空").setCode(SaErrorCode.CODE_10032);
}
listenerList.add(listener);
}
/**
* 注册一组侦听器
* @param listenerList /
*/
public static void registerListenerList(List<SaTokenListener> listenerList) {
if(listenerList == null) {
throw new SaTokenException("注册的侦听器集合不可以为空").setCode(SaErrorCode.CODE_10031);
}
for (SaTokenListener listener : listenerList) {
if(listener == null) {
throw new SaTokenException("注册的侦听器不可以为空").setCode(SaErrorCode.CODE_10032);
}
}
SaTokenEventCenter.listenerList.addAll(listenerList);
}
/**
* 移除一个侦听器
* @param listener /
*/
public static void removeListener(SaTokenListener listener) {
listenerList.remove(listener);
}
/**
* 移除指定类型的所有侦听器
* @param cls /
*/
public static void removeListener(Class<? extends SaTokenListener> cls) {
ArrayList<SaTokenListener> listenerListCopy = new ArrayList<>(listenerList);
for (SaTokenListener listener : listenerListCopy) {
if(cls.isAssignableFrom(listener.getClass())) {
listenerList.remove(listener);
}
}
}
/**
* 清空所有已注册的侦听器
*/
public static void clearListener() {
listenerList.clear();
}
/**
* 判断是否已经注册了指定侦听器
* @param listener /
* @return /
*/
public static boolean hasListener(SaTokenListener listener) {
return listenerList.contains(listener);
}
/**
* 判断是否已经注册了指定类型的侦听器
* @param cls /
* @return /
*/
public static boolean hasListener(Class<? extends SaTokenListener> cls) {
for (SaTokenListener listener : listenerList) {
if(cls.isAssignableFrom(listener.getClass())) {
return true;
}
}
return false;
}
// --------- 事件发布
/**
* 事件发布:xx 账号登录
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue 本次登录产生的 token 值
* @param loginModel 登录参数
*/
public static void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
for (SaTokenListener listener : listenerList) {
listener.doLogin(loginType, loginId, tokenValue, loginModel);
}
}
/**
* 事件发布:xx 账号注销
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue token值
*/
public static void doLogout(String loginType, Object loginId, String tokenValue) {
for (SaTokenListener listener : listenerList) {
listener.doLogout(loginType, loginId, tokenValue);
}
}
/**
* 事件发布:xx 账号被踢下线
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue token值
*/
public static void doKickout(String loginType, Object loginId, String tokenValue) {
for (SaTokenListener listener : listenerList) {
listener.doKickout(loginType, loginId, tokenValue);
}
}
/**
* 事件发布:xx 账号被顶下线
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue token值
*/
public static void doReplaced(String loginType, Object loginId, String tokenValue) {
for (SaTokenListener listener : listenerList) {
listener.doReplaced(loginType, loginId, tokenValue);
}
}
/**
* 事件发布:xx 账号被封禁
* @param loginType 账号类别
* @param loginId 账号id
* @param service 指定服务
* @param level 封禁等级
* @param disableTime 封禁时长,单位: 秒
*/
public static void doDisable(String loginType, Object loginId, String service, int level, long disableTime) {
for (SaTokenListener listener : listenerList) {
listener.doDisable(loginType, loginId, service, level, disableTime);
}
}
/**
* 事件发布:xx 账号被解封
* @param loginType 账号类别
* @param loginId 账号id
* @param service 指定服务
*/
public static void doUntieDisable(String loginType, Object loginId, String service) {
for (SaTokenListener listener : listenerList) {
listener.doUntieDisable(loginType, loginId, service);
}
}
/**
* 事件发布:xx 账号完成二级认证
* @param loginType 账号类别
* @param tokenValue token值
* @param service 指定服务
* @param safeTime 认证时间,单位:秒
*/
public static void doOpenSafe(String loginType, String tokenValue, String service, long safeTime) {
for (SaTokenListener listener : listenerList) {
listener.doOpenSafe(loginType, tokenValue, service, safeTime);
}
}
/**
* 事件发布:xx 账号关闭二级认证
* @param loginType 账号类别
* @param service 指定服务
* @param tokenValue token值
*/
public static void doCloseSafe(String loginType, String tokenValue, String service) {
for (SaTokenListener listener : listenerList) {
listener.doCloseSafe(loginType, tokenValue, service);
}
}
/**
* 事件发布:创建了一个新的 SaSession
* @param id SessionId
*/
public static void doCreateSession(String id) {
for (SaTokenListener listener : listenerList) {
listener.doCreateSession(id);
}
}
/**
* 事件发布:一个 SaSession 注销了
* @param id SessionId
*/
public static void doLogoutSession(String id) {
for (SaTokenListener listener : listenerList) {
listener.doLogoutSession(id);
}
}
/**
* 事件发布:指定 Token 续期成功
*
* @param tokenValue token 值
* @param loginId 账号id
* @param timeout 续期时间
*/
public static void doRenewTimeout(String tokenValue, Object loginId, long timeout) {
for (SaTokenListener listener : listenerList) {
listener.doRenewTimeout(tokenValue, loginId, timeout);
}
}
/**
* 事件发布:有新的全局组件载入到框架中
* @param compName 组件名称
* @param compObj 组件对象
*/
public static void doRegisterComponent(String compName, Object compObj) {
for (SaTokenListener listener : listenerList) {
listener.doRegisterComponent(compName, compObj);
}
}
/**
* 事件发布:有新的 StpLogic 载入到框架中
* @param stpLogic /
*/
public static void doSetStpLogic(StpLogic stpLogic) {
for (SaTokenListener listener : listenerList) {
listener.doSetStpLogic(stpLogic);
}
}
/**
* 事件发布:有新的全局配置载入到框架中
* @param config /
*/
public static void doSetConfig(SaTokenConfig config) {
for (SaTokenListener listener : listenerList) {
listener.doSetConfig(config);
}
}
}
?这里就是监听器的一些增删改查操作,还有事件发布的触发。
按照逻辑来如果我需要在登录的时候写一个监听器,那么我在登录操作的逻辑中就会调用这个方法去发布事件。
呐,确实是在登录的试试操作,验证通过。
?这里有小伙伴就会有疑问,那我自定义的监听器是怎么假如集合容器的呢?按照官网来的方式:
新建java类
,实现SaTokenListener
接口,并添加上注解@Component
,保证此类被SpringBoot
扫描到。
package com.example.demo.satoken.listener;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.SaLoginModel;
import java.util.ArrayList;
import java.util.List;
/**
* @author Jerry
* @date 2024-01-22 14:25
* Sa-Token-Plus 事件中心 事件发布器
*/
public class SaTokenEventCenterPlus {
// --------- 注册侦听器
private static List<SaTokenListenerPlus> LISTENER_LIST = new ArrayList<>();
static {
// 初始化一些默认的监听器
//LISTENER_LIST.add();
}
/**
* 获取已注册的所有侦听器
*
* @return /
*/
public static List<SaTokenListenerPlus> getListenerList() {
return LISTENER_LIST;
}
/**
* 重置侦听器集合
*
* @param listenerList /
*/
public static void setListenerList(List<SaTokenListenerPlus> listenerList) {
if (listenerList == null) {
throw new SaTokenException("重置的侦听器集合不可以为空").setCode(10031);
}
SaTokenEventCenterPlus.LISTENER_LIST = listenerList;
}
/**
* 注册一个侦听器
*
* @param listener /
*/
public static void registerListener(SaTokenListenerPlus listener) {
if (listener == null) {
throw new SaTokenException("注册的侦听器不可以为空").setCode(10032);
}
LISTENER_LIST.add(listener);
}
/**
* 注册一组侦听器
*
* @param listenerList /
*/
public static void registerListenerList(List<SaTokenListenerPlus> listenerList) {
if (listenerList == null) {
throw new SaTokenException("注册的侦听器集合不可以为空").setCode(10031);
}
for (SaTokenListenerPlus listener : listenerList) {
if (listener == null) {
throw new SaTokenException("注册的侦听器不可以为空").setCode(10032);
}
}
SaTokenEventCenterPlus.LISTENER_LIST.addAll(listenerList);
}
/**
* 移除一个侦听器
*
* @param listener /
*/
public static void removeListener(SaTokenListenerPlus listener) {
LISTENER_LIST.remove(listener);
}
/**
* 移除指定类型的所有侦听器
*
* @param cls /
*/
public static void removeListener(Class<? extends SaTokenListenerPlus> cls) {
ArrayList<SaTokenListenerPlus> listenerListCopy = new ArrayList<>();
for (SaTokenListenerPlus listener : listenerListCopy) {
if (cls.isAssignableFrom(listener.getClass())) {
LISTENER_LIST.remove(listener);
}
}
}
/**
* 清空所有已注册的侦听器
*/
public static void clearListener() {
LISTENER_LIST.clear();
}
/**
* 判断是否已经注册了指定侦听器
*
* @param listener /
* @return /
*/
public static boolean hasListener(SaTokenListenerPlus listener) {
return LISTENER_LIST.contains(listener);
}
/**
* 判断是否已经注册了指定类型的侦听器
*
* @param cls /
* @return /
*/
public static boolean hasListener(Class<? extends SaTokenListenerPlus> cls) {
for (SaTokenListenerPlus listener : LISTENER_LIST) {
if (cls.isAssignableFrom(listener.getClass())) {
return true;
}
}
return false;
}
// --------- 事件发布
/**
* 事件发布:xx 账号登录
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue 本次登录产生的 token 值
* @param loginModel 登录参数
*/
public static void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
for (SaTokenListenerPlus listener : LISTENER_LIST) {
listener.doLogin(loginType, loginId, tokenValue, loginModel);
}
}
/**
* 事件发布:xx 账号注销
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue token值
*/
public static void doLogout(String loginType, Object loginId, String tokenValue) {
for (SaTokenListenerPlus listener : LISTENER_LIST) {
listener.doLogout(loginType, loginId, tokenValue);
}
}
}
package com.example.demo.satoken.listener;
import cn.dev33.satoken.stp.SaLoginModel;
/**
* @author Jerry
* @date 2024-01-22 14:23
* Sa-Token-plus 自定义侦听器
*/
public interface SaTokenListenerPlus {
/**
* 每次登录时触发
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue 本次登录产生的 token 值
* @param loginModel 登录参数
*/
void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel);
/**
* 每次注销时触发
* @param loginType 账号类别
* @param loginId 账号id
* @param tokenValue token值
*/
void doLogout(String loginType, Object loginId, String tokenValue);
}
package com.example.demo.satoken.listener;
import cn.dev33.satoken.stp.SaLoginModel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author Jerry
* @date 2024-01-22 14:32
* 自定义监听器
*/
@Slf4j
@Component
public class UserActionsListener implements SaTokenListenerPlus {
@Override
public void doLogin(String loginType, Object loginId, String tokenValue, SaLoginModel loginModel) {
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
}
@Override
public void doLogout(String loginType, Object loginId, String tokenValue) {
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
}
}