这里我们学习一下Spring的订阅发布功能
参考资料:
https://www.jianshu.com/p/e2d257ce410d?from=timeline&isappinstalled=0
https://www.iteye.com/blog/butteryrose-2283056
整个功能分为三部分:事件,发布 ,订阅
事件必须继承ApplicationEvent,啥也不说贴代码:
/**
* 系统日志事件
*/
public class SysLogininforEvent extends ApplicationEvent
{
private static final long serialVersionUID = -9084676463718966036L;
public SysLogininforEvent(SysLogininfor source)
{
super(source);
}
}
SysLogininfor:是自定义的一个bean,存放发送的事件信息;
事件发布方式很简单
applicationContext.publishEvent(new SysLogininforEvent(logininfor));
ApplicationContext的获取一般都是实现ApplicationContextAware
我这里贴出工具代码:
@Slf4j
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean
{
private static ApplicationContext applicationContext = null;
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext()
{
return applicationContext;
}
/**
* 实现ApplicationContextAware接口, 注入Context到静态变量中.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext)
{
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 清除SpringContextHolder中的ApplicationContext为Null.
*/
public static void clearHolder()
{
if (log.isDebugEnabled())
{
log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
}
applicationContext = null;
}
/**
* 发布事件
*
* @param event
*/
public static void publishEvent(ApplicationEvent event)
{
if (applicationContext == null)
{
return;
}
applicationContext.publishEvent(event);
}
/**
* 实现DisposableBean接口, 在Context关闭时清理静态变量.
*/
@Override
@SneakyThrows
public void destroy()
{
SpringContextHolder.clearHolder();
}
}
事件监听器(方式一:实现ApplicationListener):
@Component
public class SysLogininforEventListener implements ApplicationListener<SysLogininforEvent> {
private static final Logger logger = LoggerFactory.getLogger(SysLogininforEventListener.class);
@Override
public void onApplicationEvent(SysLogininforEventevent) {
//TODO
}}
事件监听器(方式二:@EventListener):
/**
* 异步监听日志事件
*/
@Slf4j
@AllArgsConstructor
public class LogListener
{
private final RemoteLogService remoteLogService;
@Async
@Order
@EventListener(SysOperLogEvent.class)
public void listenOperLog(SysOperLogEvent event)
{
SysOperLog sysOperLog = (SysOperLog) event.getSource();
log.info("远程操作日志记录成功:{}", sysOperLog);
}
}