subject代表用户访问服务器的一些操作:比做登录、登出,查看角色/权限、
同时可获取session如:subject.getSession(),该接品,如果之前不存在session,则创建session。创建过程大致为:
subject委托SecurityManager创建、SecurityManager委托SessionManager创建,SessionManager通过SessionFactory工厂创建。由此可见,shiro创建的过程分工明确。
创建过程分析如下。
(1)在DelegatingSubject类中可以获取Session:
public Session getSession(boolean create) {
.......
SessionContext sessionContext = createSessionContext();
//创建Session上下文,context有个backMap,存放创建Session时所需的数据
Session session = this.securityManager.start(sessionContext);
this.session = decorate(session);//创建代理session,当session.stop()调用时,清空subject的session
.......
return this.session;//返回代理session
}(2)SecurityManager委托sessionManager(DefaultSessionManage)处理Session的创建:
1 public Session start(SessionContext context) throws AuthorizationException {
2 return this.sessionManager.start(context);
3 }*注意:DefaultSessionManage的内部架构为:

(3)AbstractNativeSessionManager创建Session并管理Session:
public Session start(SessionContext context) {
Session session = createSession(context);//通过模板模式,子类实现通过上下仍创建Session
applyGlobalSessionTimeout(session);//更新sessionDAO的sessions(map<String,session>)
onStart(session, context);//一个槽点,待子类实现
notifyStart(session);//注册的监听器开始执行
//Don't expose the EIS-tier Session object to the client-tier:
return createExposedSession(session, context);//创建暴露的Session
}(4)到此Session的创建完成,及细节代码如下:AbstractNativeSessionManager交给AbstractValidatingSessionManager处理:
protected Session createSession(SessionContext context) throws AuthorizationException {
enableSessionValidationIfNecessary();
//创建Session之前,先起一个Session自动定时任务的线程去执行,校验sessionDAO的sessions是否过期。
return doCreateSession(context);
}
//
private void enableSessionValidationIfNecessary() {
SessionValidationScheduler scheduler = getSessionValidationScheduler();
if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) {
enableSessionValidation();
}
}
//
protected void enableSessionValidation() {
SessionValidationScheduler scheduler = getSessionValidationScheduler();
if (scheduler == null) {
scheduler = createSessionValidationScheduler();
//scheduler = new ExecutorServiceSessionValidationScheduler(this);scheduler.setInterval(getSessionValidationInterval());
setSessionValidationScheduler(scheduler);
}
if (log.isInfoEnabled()) {
log.info("Enabling session validation scheduler...");
}
scheduler.enableSessionValidation();//自动任务启动执行
afterSessionValidationEnabled();//一个槽点,待子类实现
}(5)ExecutorServiceSessionValidationScheduler验证Session的过期:
/**
* Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals
* and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down
*/
//TODO Implement an integration test to test for jvm exit as part of the standalone example
// (so we don't have to change the unit test execution model for the core module)
public void enableSessionValidation() {
if (this.interval > 0l) {
this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
this.enabled = true;
}
}
public void run() {
if (log.isDebugEnabled()) {
log.debug("Executing session validation...");
}
long startTime = System.currentTimeMillis();
this.sessionManager.validateSessions();//ExecutorServiceSessionValidationSchedule的在被SessionManager创建里,
long stopTime = System.currentTimeMillis();
if (log.isDebugEnabled()) {
log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
}
}(6)AbstractValidatingSessionManager验证Session的过期:
/**
* @see ValidatingSessionManager#validateSessions()
*/
public void validateSessions() {
if (log.isInfoEnabled()) {
log.info("Validating all active sessions...");
}
int invalidCount = 0;
Collection<Session> activeSessions = getActiveSessions();//获取取保存的Session
if (activeSessions != null && !activeSessions.isEmpty()) {
for (Session s : activeSessions) {
try {
//simulate a lookup key to satisfy the method signature.
//this could probably stand to be cleaned up in future versions:
SessionKey key = new DefaultSessionKey(s.getId());
validate(s, key);
} catch (InvalidSessionException e) {
if (log.isDebugEnabled()) {
boolean expired = (e instanceof ExpiredSessionException);
String msg = "Invalidated session with id [" + s.getId() + "]" +
(expired ? " (expired)" : " (stopped)");
log.debug(msg);
}
invalidCount++;
}
}
}
if (log.isInfoEnabled()) {
String msg = "Finished session validation.";
if (invalidCount > 0) {
msg += " [" + invalidCount + "] sessions were stopped.";
} else {
msg += " No sessions were stopped.";
}
log.info(msg);
}
}
//类DefaultSessionManager实现getActiveSessions接口
protected abstract Collection<Session> getActiveSessions();
protected Collection<Session> getActiveSessions() {
Collection<Session> active = sessionDAO.getActiveSessions();
return active != null ? active : Collections.<Session>emptySet();
}(7)Session的校验完成,接下来是DefaultSessionManager进行Session的创建:
protected Session doCreateSession(SessionContext context) {
Session s = newSessionInstance(context);
if (log.isTraceEnabled()) {
log.trace("Creating session for host {}", s.getHost());
}
create(s);
return s;
}
protected Session newSessionInstance(SessionContext context) {
return getSessionFactory().createSession(context);
}
protected void create(Session session) {
if (log.isDebugEnabled()) {
log.debug("Creating new EIS record for new session instance [" + session + "]");
}
sessionDAO.create(session);
}(8)DefaultSessionManager委托Session(MemorySessionDAO)维护Session:
protected Serializable doCreate(Session session) {
Serializable sessionId = generateSessionId(session);
assignSessionId(session, sessionId);
storeSession(sessionId, session);
return sessionId;
}
protected Session storeSession(Serializable id, Session session) {
if (id == null) {
throw new NullPointerException("id argument cannot be null.");
}
return sessions.putIfAbsent(id, session);
}(9) 创建并维护Session之后,AbstractNativeSessionManager交给注册好的监听器,监听器调用启动onStart接口
protected void notifyStart(Session session) {
2 for (SessionListener listener : this.listeners) {
3 listener.onStart(session);
4 }
5 }(10)最后创建委托Session,
protected Session createExposedSession(Session session, SessionContext context) {
return new DelegatingSession(this, new DefaultSessionKey(session.getId()));
}(11)最后Subject创建自己的代理Session,主要用来拦截stop方法:
protected Session decorate(Session session) {
if (session == null) {
throw new IllegalArgumentException("session cannot be null");
}
return new StoppingAwareProxiedSession(session, this);
}
private class StoppingAwareProxiedSession extends ProxiedSession {
private final DelegatingSubject owner;
private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) {
super(target);
owner = owningSubject;
}
16 public void stop() throws InvalidSessionException {
super.stop();
owner.sessionStopped();
}
}总结:Session(SimpleSession)在DefaultSessionManage中创建时,被封装在DelegatingSession中,在subject中又被装饰为代理session(StoppingAwareProxiedSession),原始的数据很好的保存,使的客户端不可随意修改原始的Session
........
以上就是关于shiro的源码学习之Session session = getSession()的实例分析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号