Sie haben Sitzungsstruktur Und nun ohne weitere Umschweife die Bilder Wenn wir die obige Abbildung genauer betrachten, können wir folgende Schlussfolgerungen ziehen
Warum müssen wir Schauen wir uns zunächst die Wrapper-Klasse HttpSession an. Standardsitzungsfassade In diesem Kurs können wir die praktische Anwendung des Erscheinungsmusters (Facde) erlernen. Die Definition finden Sie weiter unten. öffentliche Klasse StandardSessionFacade implementiert HttpSession Wie implementiert diese Klasse also die Session-Funktion? Aus dem folgenden Code ist nicht schwer zu erkennen, dass diese Klasse keine echte Implementierungsklasse von HttpSession ist, sondern ein Wrapper der echten HttpSession-Implementierungsklasse, der nur die Methoden in der HttpSession-Schnittstelle verfügbar macht, was im Entwurfsmuster der Fassadenmodus ist. private letzte HttpSession-Sitzung; öffentliche StandardSessionFacade(HttpSession-Sitzung) { diese.sitzung = Sitzung; } Warum verwenden wir also nicht einfach die Implementierungsklasse HttpSession? Aus Abbildung 1 können wir erkennen, dass die tatsächliche Implementierungsklasse von HttpSession Wenn wir Können wir im weiteren Verlauf direkt auf Tatsächlich ist es möglich. Wir können @GetMapping("/s") öffentlicher String sessionTest(HttpSession httpSession) wirft ClassNotFoundException, NoSuchFieldException, IllegalAccessException { StandardSessionFacade-Sitzung = (StandardSessionFacade) httpSession; Klasse Zielklasse = Klasse.fürName(session.getClass().getName()); //Sichtbarkeit ändern Feld standardSessionField = targetClass.getDeclaredField("session"); standardSessionField.setAccessible(true); //StandardSession abrufen standardSession = (StandardSession) standardSessionField.get(session); return standardSession.getManager().toString(); } Standardsitzung Die Definition dieser Klasse lautet wie folgt öffentliche Klasse StandardSession implementiert HttpSession, Sitzung, Serialisierbar Anhand ihrer Schnittstelle können wir erkennen, dass diese Klasse zusätzlich zu den von In Abbildung 1 wissen wir bereits, dass Serialisierung Erinnern Sie sich, dass wir im letzten Abschnitt @GetMapping("/s") public void sessionTest(HttpSession httpSession, HttpServletResponse response) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, IOException { StandardSessionFacade-Sitzung = (StandardSessionFacade) httpSession; Klasse Zielklasse = Klasse.fürName(session.getClass().getName()); //Sichtbarkeit ändern Feld standardSessionField = targetClass.getDeclaredField("session"); standardSessionField.setAccessible(true); //StandardSession abrufen standardSession = (StandardSession) standardSessionField.get(session); //Einige Daten zur Beobachtung speichernstandardSession.setAttribute("msg","hallo, Welt"); standardSession.setAttribute("Benutzer","Benutzername"); standardSession.setAttribute("Passwort", "Gefällt mir"); standardSession.setAttribute("tel", 10086L); //Schreibe das serialisierte Ergebnis direkt in die HTTP-Antwort ObjectOutputStream objectOutputStream = new ObjectOutputStream(response.getOutputStream()); Standardsitzung.writeObjectData(objectOutputStream); } Wenn nichts schief geht, führt der Browser, der auf diese Schnittstelle zugreift, den Downloadvorgang durch und erhält schließlich eine Datei Verwenden Sie Es ist nicht empfehlenswert, zu untersuchen, wie serialisierte Dateien Daten organisieren, da dies nicht sehr aussagekräftig ist. Wenn Sie wirklich interessiert sind, empfehlen wir Ihnen, den folgenden Code zu lesen: Zuhörer Im JavaEE-Standard können wir Sitzungsänderungen überwachen, indem wir public void setAttribute(Stringname, Objektwert, boolean benachrichtigen) { //Irrelevanten Code weglassen//Den oben konfigurierten Ereignis-Listener abrufenObject listeners[] = context.getApplicationEventListeners(); wenn (Listeners == null) { zurückkehren; } für (int i = 0; i < listeners.length; i++) { //Nur HttpSessionAttributeListener kann ausgeführt werden, wenn (!(listeners[i] instanceof HttpSessionAttributeListener)) { weitermachen; } HttpSessionAttributeListener listener = (HttpSessionAttributeListener) listeners[i]; versuchen { //Rufen Sie die Verarbeitungsmethode des Listeners im aktuellen Thread auf, wenn (ungebunden != null) { if (ungebunden != Wert || manager.getNotifyAttributeListenerOnUnchangedValue()) { //Wenn der Wert eines Schlüssels geändert wird, rufen Sie die Methode „attributeReplaced“ des Listeners auf. context.fireContainerEvent("beforeSessionAttributeReplaced", listener); wenn (Ereignis == null) { Ereignis = neues HttpSessionBindingEvent(getSession(), Name, ungebunden); } listener.attributeErsetzt(Ereignis); Kontext.fireContainerEvent("afterSessionAttributeReplaced", Listener); } } anders { //Wenn ein neuer Schlüssel hinzugefügt wird, führen Sie die Methode attributeAdded aus. context.fireContainerEvent("beforeSessionAttributeAdded", listener); wenn (Ereignis == null) { Ereignis = neues HttpSessionBindingEvent(getSession(), Name, Wert); } listener.attributeAdded(Ereignis); Kontext.fireContainerEvent("afterSessionAttributeAdded", Listener); } } fangen (Wurfbares t) { //Ausnahmebehandlung} } } Lebenszyklus einer Sitzung So speichern Sie die Sitzung Nachdem wir den Aufbau einer Sitzung verstanden haben, gilt es zu klären, wann Schauen wir uns zunächst den öffentliche StandardSession(Manager manager) { //Rufen Sie den Konstruktor der Object-Klasse auf, der standardmäßig aufgerufen wurde. //Deklarieren Sie ihn hier noch einmal. Ich kenne seinen Zweck nicht. Vielleicht hat diese Klasse bereits eine übergeordnete Klasse? super(); dieser.manager = Manager; //Ob der Zugriffszähler aktiviert werden soll, wenn (ACTIVITY_CHECK) { Zugriffsanzahl = neue AtomicInteger(); } } Beim Erstellen Wir wenden unsere Aufmerksamkeit geschützte Map<String, Session> Sitzungen = neue ConcurrentHashMap<>(); Durch Nachschlagen dieser Eigenschaft können wir feststellen, dass alle mit der Sitzung in Zusammenhang stehenden Vorgänge durch Ausführen So erstellen Sie eine Sitzung Wie wird also die Sitzung erstellt? Ich habe die folgende Methode
(1000*60*Zähler)/(int)(jetzt – ältester)
öffentliche Sitzung erstellenSession(String sessionId) { // Überprüfen Sie, ob die Sitzung das Limit überschreitet, und werfen Sie in diesem Fall eine Ausnahme, wenn ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { abgelehnte Sitzungen++; neue TooManyActiveSessionsException werfen( sm.getString("managerBase.createSession.ise"), maxActiveSessions); } //Diese Methode erstellt ein StandardSession-Objekt Session session = createEmptySession(); //Initialisiere die erforderlichen Attribute in der Sitzung session.setNew(true); //Ist die Sitzung verfügbar? session.setValid(true); //Erstellungszeit session.setCreationTime(System.currentTimeMillis()); //Maximales Sitzungstimeout festlegen session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60); String-ID = Sitzungs-ID; wenn (id == null) { id = generateSessionId(); } Sitzung.setId(id); Sitzungszähler++; //Zeichne den Zeitpunkt der Sitzungserstellung auf. Dieser wird zum Zählen der Erstellungsrate der Sitzung verwendet. //Ebenso gibt es ExpireRate, die Ablaufrate der Sitzung. //Da andere Threads möglicherweise mit sessionCreationTiming arbeiten, muss SessionTiming gesperrt werden timing = new SessionTiming(session.getCreationTime(), 0); synchronisiert (sessionCreationTiming) { //sessionCreationTiming ist LinkedList //Daher entfernt die Umfrage die Daten am Anfang der verknüpften Liste, also die ältesten Daten sessionCreationTiming.add(timing); Sitzungserstellungstiming.poll(); } Sitzung zurückgeben; } Zerstören einer Sitzung Um die Sitzung zu zerstören, muss sie aus @Überschreiben public void entfernen(Sitzung Sitzung, boolean update) { //Überprüfen Sie, ob es notwendig ist, die Informationen zu abgelaufenen Sitzungen zu zählen, wenn (Update) { lange ZeitJetzt = System.currentTimeMillis(); int timeAlive = (int) (ZeitJetzt - Sitzung.getCreationTimeInternal())/1000; Aktualisieren Sie SessionMaxAliveTime(timeAlive); abgelaufeneSitzungen.incrementAndGet(); SessionTiming-Zeitgebung = neues SessionTiming (aktuelle Zeit, Lebenszeit); synchronisiert (sessionExpirationTiming) { SitzungsablaufTiming.add(Zeitpunkt); Sitzungsablauftiming.poll(); } } //Sitzung aus Map entfernen if (session.getIdInternal() != null) { Sitzungen.entfernen(session.getIdInternal()); } } Zeit der Zerstörung Aktive Zerstörung Wir können die Sitzung zerstören, indem öffentliche Leere ungültig machen() { wenn (!isValidInternal()) neue IllegalStateException werfen (sm.getString("standardSession.invalidate.ise")); // Diese Sitzung ablaufen lassen erlöschen(); } Der Code der @Überschreiben öffentliche Leere abgelaufen () { ablaufen(wahr); } öffentliche Leere abgelaufen (Boolesche Benachrichtigung) { //Code auslassen//Sitzung aus ConcurrentHashMap entfernen manager.remove(this, true); //Der ausgelassene Code dient hauptsächlich dazu, jeden Listener über die Zerstörung der Sitzung zu benachrichtigen} Timeout-Zerstörung Zusätzlich zur aktiven Zerstörung können wir eine Ablaufzeit für die Sitzung festlegen. Wenn die Zeit erreicht ist, wird die Sitzung vom Hintergrundthread aktiv zerstört. Wir können eine kürzere Ablaufzeit für die Sitzung festlegen und dann Wie in der Abbildung unten gezeigt, legen wir ein Timeout von 30 Sekunden für die Sitzung fest. Dann Setzen Sie einen Haltepunkt auf die Methode und warten Sie 30 Sekunden, wie unten gezeigt Tomcat startet einen Hintergrundthread, um die Methode @Überschreiben public void Hintergrundprozess() { Anzahl = (Anzahl + 1) % processExpiresFrequency; wenn (Anzahl == 0) Prozess läuft ab(); } public void Prozess läuft ab() { lange ZeitJetzt = System.currentTimeMillis(); Sitzung Sitzungen[] = findSessions(); int expireHere = 0; wenn(log.isDebugEnabled()) log.debug("Starten Sie ablaufende Sitzungen " + getName() + " um " + timeNow + " sessioncount " + sessions.length); //Aus dem JConsole-Diagramm können wir ersehen, dass isValid dazu führen kann, dass die Methode expire aufgerufen wird für (int i = 0; i < session.length; i++) { wenn (sessions[i]!=null und !sessions[i].isValid()) { läuft hier ab++; } } langes timeEnd = System.currentTimeMillis(); wenn(log.isDebugEnabled()) log.debug("Ende abgelaufener Sitzungen " + getName() + " processingTime " + (timeEnd - timeNow) + " abgelaufene Sitzungen: " + expireHere); Verarbeitungszeit += (Endzeit – Jetztzeit); } Wir können uns die Kommentare in der Schnittstelle /** * Diese Methode wird vom Kontext/Container in regelmäßigen Abständen aufgerufen * Basis und ermöglicht dem Manager die Umsetzung * eine Methode, die periodische Aufgaben ausführt, wie z. B. das Ablaufen von Sitzungen usw. */ öffentliche void Hintergrundprozess(); Zusammenfassen Die Datenstruktur von Session ist in der folgenden Abbildung dargestellt. Einfach ausgedrückt wird Dies bedeutet, dass es leistungsfähiger ist, die diskreten Daten in einem Objekt zu kapseln, anstatt der Sitzung diskrete Daten hinzuzufügen, wie unten gezeigt. //schlecht httpSession.setAttribute("Benutzer","Benutzername"); httpSession.setAttribute("Spitzname","Gefällt mir"); httpSession.setAttribute("Geschlecht", "Geschlecht"); .... //Gut Benutzername = userDao.getUser() httpSession.setAttribute("Benutzer", nein); Wenn Sie einen Listener für die Sitzung konfigurieren, wird bei allen Änderungen an der Sitzung die Listener-Methode direkt im aktuellen Thread ausgeführt. Daher sollten Sie am besten keine Methoden ausführen, die den Listener blockieren könnten . Tomcat startet einen Hintergrund-Thread, um regelmäßig Gedankenmigration Algorithmus zur Objektgenerierungsrate Dieser Algorithmusentwurf ist recht interessant und kann auch auf andere Projekte angewendet werden, daher folgt die folgende Zusammenfassung. Zuerst wird eine verknüpfte Liste fester Größe (sagen wir 100) generiert und dann mit Nullelementen gefüllt. Wenn ein neues Objekt erstellt wird, wird die Erstellungszeit am Ende der verknüpften Liste hinzugefügt (natürlich ist es das gekapselte Objekt) und dann wird der Kopfknoten der verknüpften Liste entfernt. Zu diesem Zeitpunkt ist das entfernte Objekt entweder ein Nullknoten oder der Knoten, der zuerst zur verknüpften Liste hinzugefügt wurde. Wenn Sie die Objektgenerierungsrate berechnen möchten, zählen Sie die Anzahl der nicht-null-Elemente in der verknüpften Liste und dividieren Sie sie durch die Differenz zwischen der aktuellen Zeit und der Zeit, zu der das Objekt erstmals erstellt wurde, um die Rate zu erhalten. (Beachten Sie die Umrechnung der Zeiteinheiten) Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, er wird für jedermanns Studium hilfreich sein. Ich hoffe auch, dass jeder 123WORDPRESS.COM unterstützen wird. Das könnte Sie auch interessieren:
|
<<: Grundlegender JSON-Betriebsleitfaden in MySQL 5.7
>>: Detaillierte Hinweise zu React für Einsteiger
Häufig gestellte Fragen Der Zugriff für den Benut...
Es ist sehr einfach, Daten und Tabellen in MySQL ...
Inhaltsverzeichnis Vorbereitung Installieren Sie ...
Installieren Zuerst müssen Sie Java und Scala ins...
1. Laden Sie mysql-5.7.17-winx64.zip herunter; Li...
In diesem Artikelbeispiel wird der spezifische JS...
In diesem Artikel wird der spezifische Code des V...
Inhaltsverzeichnis Überblick Funktionssignatur Op...
1. Laden Sie mysql-8.0.15 herunter, installieren ...
Einführung in die Sudo-Autoritätsdelegierung su-S...
Laden Sie MySQL 5.7.20 / 5.7.21 herunter, install...
Um mit Standard-CSS3 den Schatteneffekt eines Ele...
Inhaltsverzeichnis 1. Ergänzende Wissenspunkte: i...
1. Einleitung Presto ist eine Open-Source-SQL-Abf...
GitHub-Adresse: https://github.com/dmhsq/dmhsq-my...