项目背景: shiro 1.3 + quartz 2.x
2018-9-11 22:20:35补充:
经过测试,本人发现 ,通过实现 org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler 同样能解决相关问题,具体原因正在查找.
利用该类进行实现则不必自定义了.完整配置如下:(异同部分已高亮)
<!-- 配置session的定时验证检测程序类,以让无效的session释放 --> <bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.ExecutorServiceSessionValidationScheduler"> <!-- 设置session的失效扫描间隔,单位为毫秒 --> <property name="interval" value="1800000"/> <!-- 随后还需要定义有一个会话管理器的程序类的引用 --> <property name="sessionManager" ref="sessionManager"/> </bean>
如果上面的方式不能解决问题,那么可以选择下面这种方式:
-------------------------------------------------------------------------华丽的分割线--------------------------------------------------------------------------------------------
期初的session会话配置如下:
<bean id="sessionValidationScheduler" class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler"> <!-- 设置session的失效扫描间隔,单位为毫秒 --> <property name="sessionValidationInterval" value="1800000"/> <!-- 随后还需要定义有一个会话管理器的程序类的引用 --> <property name="sessionManager" ref="sessionManager"/> </bean>
class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler" 默认shiro使用的是这个来编译,但是quartz2.x之后实现方式变了,所以需要自定义实现:自定义实现类如下:
代码是从网上找的,也试过没啥问题.直接复制就好,不需要做修改.
package xxxxx; import org.apache.shiro.session.mgt.SessionValidationScheduler; import org.apache.shiro.session.mgt.ValidatingSessionManager; import org.apache.shiro.session.mgt.quartz.QuartzSessionValidationJob; import org.quartz.JobBuilder; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleScheduleBuilder; import org.quartz.SimpleTrigger; import org.quartz.TriggerBuilder; import org.quartz.TriggerKey; import org.quartz.impl.StdSchedulerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Quartz2SessionValidationScheduler implements SessionValidationScheduler { public static final long DEFAULT_SESSION_VALIDATION_INTERVAL = 3600000L; private static final String JOB_NAME = "SessionValidationJob"; private static final Logger log = LoggerFactory .getLogger(Quartz2SessionValidationScheduler.class); private Scheduler scheduler; private boolean schedulerImplicitlyCreated = false; private boolean enabled = false; private ValidatingSessionManager sessionManager; private long sessionValidationInterval = 3600000L; public Quartz2SessionValidationScheduler() { } public Quartz2SessionValidationScheduler( ValidatingSessionManager sessionManager) { this.sessionManager = sessionManager; } protected Scheduler getScheduler() throws SchedulerException { if (this.scheduler == null) { this.scheduler = StdSchedulerFactory.getDefaultScheduler(); this.schedulerImplicitlyCreated = true; } return this.scheduler; } public void setScheduler(Scheduler scheduler) { this.scheduler = scheduler; } public void setSessionManager(ValidatingSessionManager sessionManager) { this.sessionManager = sessionManager; } public boolean isEnabled() { return this.enabled; } public void setSessionValidationInterval(long sessionValidationInterval) { this.sessionValidationInterval = sessionValidationInterval; } public void enableSessionValidation() { if (log.isDebugEnabled()) { log.debug("Scheduling session validation job using Quartz with session validation interval of [" + this.sessionValidationInterval + "]ms..."); } try { SimpleTrigger trigger = TriggerBuilder .newTrigger() .startNow() .withIdentity(JOB_NAME, "DEFAULT") .withSchedule( SimpleScheduleBuilder.simpleSchedule() .withIntervalInMilliseconds( sessionValidationInterval)).build(); JobDetail detail = JobBuilder .newJob(QuartzSessionValidationJob.class) .withIdentity(JOB_NAME, "DEFAULT").build(); detail.getJobDataMap().put("sessionManager", this.sessionManager); Scheduler scheduler = getScheduler(); scheduler.scheduleJob(detail, trigger); if (this.schedulerImplicitlyCreated) { scheduler.start(); if (log.isDebugEnabled()) { log.debug("Successfully started implicitly created Quartz Scheduler instance."); } } this.enabled = true; if (log.isDebugEnabled()) log.debug("Session validation job successfully scheduled with Quartz."); } catch (SchedulerException e) { if (log.isErrorEnabled()) log.error( "Error starting the Quartz session validation job. Session validation may not occur.", e); } } public void disableSessionValidation() { if (log.isDebugEnabled()) { log.debug("Stopping Quartz session validation job..."); } Scheduler scheduler; try { scheduler = getScheduler(); if (scheduler == null) { if (log.isWarnEnabled()) { log.warn("getScheduler() method returned a null Quartz scheduler, which is unexpected. Please check your configuration and/or implementation. Returning quietly since there is no validation job to remove (scheduler does not exist)."); } return; } } catch (SchedulerException e) { if (log.isWarnEnabled()) { log.warn( "Unable to acquire Quartz Scheduler. Ignoring and returning (already stopped?)", e); } return; } try { scheduler.unscheduleJob(new TriggerKey("SessionValidationJob", "DEFAULT")); if (log.isDebugEnabled()) log.debug("Quartz session validation job stopped successfully."); } catch (SchedulerException e) { if (log.isDebugEnabled()) { log.debug( "Could not cleanly remove SessionValidationJob from Quartz scheduler. Ignoring and stopping.", e); } } this.enabled = false; if (this.schedulerImplicitlyCreated) try { scheduler.shutdown(); } catch (SchedulerException e) { if (log.isWarnEnabled()) log.warn( "Unable to cleanly shutdown implicitly created Quartz Scheduler instance.", e); } finally { setScheduler(null); this.schedulerImplicitlyCreated = false; } } }
复制完之后修改配置:
<!-- 配置session的定时验证检测程序类,以让无效的session释放 --> <bean id="sessionValidationScheduler" class="xxxxx.Quartz2SessionValidationScheduler"> <!-- 设置session的失效扫描间隔,单位为毫秒 --> <!--shiro使用的是1.6的quartz,现程序已使用了quartz 2.x,1.6和2.x的实现方式不一样,所以这里需要自定义重新实现--> <property name="sessionValidationInterval" value="1800000"/> <!-- 随后还需要定义有一个会话管理器的程序类的引用 --> <property name="sessionManager" ref="sessionManager"/> </bean>