Heim  >  Artikel  >  Java  >  Eine Beispielanalyse von Session session = getSession() im Quellcode-Lernen von Shiro

Eine Beispielanalyse von Session session = getSession() im Quellcode-Lernen von Shiro

黄舟
黄舟Original
2017-07-24 13:26:517461Durchsuche

Betreff stellt einige Vorgänge dar, mit denen Benutzer auf den Server zugreifen können: z. B. Anmelden, Abmelden, Anzeigen von Rollen/Berechtigungen,

Gleichzeitig können Sie die Sitzung abrufen, z. B.: subject.getSession (), erstellt diese Verbindung eine Sitzung, wenn sie vor der Sitzung nicht vorhanden ist. Der Erstellungsprozess ist ungefähr wie folgt:

Subjekt beauftragt SecurityManager mit der Erstellung, SecurityManager beauftragt SessionManager mit der Erstellung und SessionManager wird über die SessionFactory-Factory erstellt. Es ist ersichtlich, dass der Prozess der Shiro-Erschaffung eine klare Arbeitsteilung aufweist.

Der Erstellungsprozess wird wie folgt analysiert.

(1)Session kann in der DelegatingSubject-Klasse abgerufen werden:

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 beauftragt sessionManager (DefaultSessionManage) mit der Erstellung von Session:

1 public Session start(SessionContext context) throws AuthorizationException {
2     return this.sessionManager.start(context);
3     }

* Hinweis: Die interne Struktur von DefaultSessionManage ist:

(3)AbstractNativeSessionManager erstellt Sitzung und verwaltet Sitzung:

public Session start(SessionContext context) {
        Session session = createSession(context);//通过模板模式,子类实现通过上下仍创建Session
        applyGlobalSessionTimeout(session);//更新sessionDAO的sessions(map<String,session>)
        onStart(session, context);//一个槽点,待子类实现
        notifyStart(session);//注册的监听器开始执行
        //Don&#39;t expose the EIS-tier Session object to the client-tier:
        return createExposedSession(session, context);//创建暴露的Session
    }

(4)An Die Erstellung dieser Sitzung ist abgeschlossen und der detaillierte Code lautet wie folgt: AbstractNativeSessionManager wird zur Verarbeitung an AbstractValidatingSessionManager übergeben:

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 überprüft den Ablauf der Sitzung:

/**
     * 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&#39;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 überprüft den Ablauf der Sitzung:

/**
     * @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)Die Sitzungsüberprüfung ist abgeschlossen, dann erstellt DefaultSessionManager die Sitzung:

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 beauftragt Sitzung (MemorySessionDAO) zum Verwalten der Sitzung:

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) Nach dem Erstellen und Verwalten der Sitzung wird der AbstractNativeSessionManager an den registrierten Listener übergeben und der Listener ruft die onStart-Schnittstelle auf

  protected void notifyStart(Session session) {
  2         for (SessionListener listener : this.listeners) {
  3             listener.onStart(session);
  4         }
  5     }

(10) Schließlich wird die delegierte Sitzung erstellt,

protected Session createExposedSession(Session session, SessionContext context) {        
return new DelegatingSession(this, new DefaultSessionKey(session.getId()));
    }

(11) Schließlich erstellt das Subjekt seine eigene Proxy-Sitzung, die hauptsächlich zum Abfangen der Stoppmethode verwendet wird:

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();
         }
       }

Zusammenfassung: Wenn die Sitzung (SimpleSession) in DefaultSessionManage erstellt wird, wird sie in DelegatingSession gekapselt und im Betreff als Proxy-Sitzung (StoppingAwareProxiedSession) dekoriert. Die Originaldaten werden gut gespeichert, sodass der Client dies nicht tun kann Ändern Sie die ursprüngliche Sitzung nach Belieben

...


Das obige ist der detaillierte Inhalt vonEine Beispielanalyse von Session session = getSession() im Quellcode-Lernen von Shiro. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Erste Schritte mit AntNächster Artikel:Erste Schritte mit Ant