学习 准备 尝试 谨慎小心

0%

Shiro源码解析之SessionManager01-Session和SessionFactory

Session

类继承图

1571641163441

Session

1571641545728

ValidatingSession

1571641575122

SimpleSession

SimpleSession 将Attribute 保存在 map对象中

1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
package org.apache.shiro.session.mgt;
20
21
import org.apache.shiro.session.ExpiredSessionException;
22
import org.apache.shiro.session.InvalidSessionException;
23
import org.apache.shiro.session.StoppedSessionException;
24
import org.apache.shiro.util.CollectionUtils;
25
import org.slf4j.Logger;
26
import org.slf4j.LoggerFactory;
27
28
import java.io.IOException;
29
import java.io.ObjectInputStream;
30
import java.io.ObjectOutputStream;
31
import java.io.Serializable;
32
import java.text.DateFormat;
33
import java.util.*;
34
35
36
/**
37
 * Simple {@link org.apache.shiro.session.Session} JavaBeans-compatible POJO implementation, intended to be used on the
38
 * business/server tier.
39
 *
40
 * @since 0.1
41
 */
42
public class SimpleSession implements ValidatingSession, Serializable {
43
44
    // Serialization reminder:
45
    // You _MUST_ change this number if you introduce a change to this class
46
    // that is NOT serialization backwards compatible.  Serialization-compatible
47
    // changes do not require a change to this number.  If you need to generate
48
    // a new number in this case, use the JDK's 'serialver' program to generate it.
49
    private static final long serialVersionUID = -7125642695178165650L;
50
51
    //TODO - complete JavaDoc
52
    private transient static final Logger log = LoggerFactory.getLogger(SimpleSession.class);
53
54
    protected static final long MILLIS_PER_SECOND = 1000;
55
    protected static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
56
    protected static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
57
58
    //serialization bitmask fields. DO NOT CHANGE THE ORDER THEY ARE DECLARED!
59
    static int bitIndexCounter = 0;
60
    private static final int ID_BIT_MASK = 1 << bitIndexCounter++;
61
    private static final int START_TIMESTAMP_BIT_MASK = 1 << bitIndexCounter++;
62
    private static final int STOP_TIMESTAMP_BIT_MASK = 1 << bitIndexCounter++;
63
    private static final int LAST_ACCESS_TIME_BIT_MASK = 1 << bitIndexCounter++;
64
    private static final int TIMEOUT_BIT_MASK = 1 << bitIndexCounter++;
65
    private static final int EXPIRED_BIT_MASK = 1 << bitIndexCounter++;
66
    private static final int HOST_BIT_MASK = 1 << bitIndexCounter++;
67
    private static final int ATTRIBUTES_BIT_MASK = 1 << bitIndexCounter++;
68
69
    // ==============================================================
70
    // NOTICE:
71
    //
72
    // The following fields are marked as transient to avoid double-serialization.
73
    // They are in fact serialized (even though 'transient' usually indicates otherwise),
74
    // but they are serialized explicitly via the writeObject and readObject implementations
75
    // in this class.
76
    //
77
    // If we didn't declare them as transient, the out.defaultWriteObject(); call in writeObject would
78
    // serialize all non-transient fields as well, effectively doubly serializing the fields (also
79
    // doubling the serialization size).
80
    //
81
    // This finding, with discussion, was covered here:
82
    //
83
    // http://mail-archives.apache.org/mod_mbox/shiro-user/201109.mbox/%3C4E81BCBD.8060909@metaphysis.net%3E
84
    //
85
    // ==============================================================
86
    private transient Serializable id;
87
    private transient Date startTimestamp;
88
    private transient Date stopTimestamp;
89
    private transient Date lastAccessTime;
90
    private transient long timeout;
91
    private transient boolean expired;
92
    private transient String host;
93
    private transient Map<Object, Object> attributes;
94
95
    public SimpleSession() {
96
        this.timeout = DefaultSessionManager.DEFAULT_GLOBAL_SESSION_TIMEOUT; //TODO - remove concrete reference to DefaultSessionManager
97
        this.startTimestamp = new Date();
98
        this.lastAccessTime = this.startTimestamp;
99
    }
100
101
    public SimpleSession(String host) {
102
        this();
103
        this.host = host;
104
    }
105
106
    ......
107
    // getter setter
108
109
    public void touch() {
110
        this.lastAccessTime = new Date();
111
    }
112
113
    public void stop() {
114
        if (this.stopTimestamp == null) {
115
            this.stopTimestamp = new Date();
116
        }
117
    }
118
119
    protected boolean isStopped() {
120
        return getStopTimestamp() != null;
121
    }
122
123
    protected void expire() {
124
        stop();
125
        this.expired = true;
126
    }
127
128
    /**
129
     * @since 0.9
130
     */
131
    public boolean isValid() {
132
        return !isStopped() && !isExpired();
133
    }
134
135
    /**
136
     * Determines if this session is expired.
137
     *
138
     * @return true if the specified session has expired, false otherwise.
139
     */
140
    protected boolean isTimedOut() {
141
142
        if (isExpired()) {
143
            return true;
144
        }
145
146
        long timeout = getTimeout();
147
148
        if (timeout >= 0l) {
149
150
            Date lastAccessTime = getLastAccessTime();
151
152
            if (lastAccessTime == null) {
153
                String msg = "session.lastAccessTime for session with id [" +
154
                        getId() + "] is null.  This value must be set at " +
155
                        "least once, preferably at least upon instantiation.  Please check the " +
156
                        getClass().getName() + " implementation and ensure " +
157
                        "this value will be set (perhaps in the constructor?)";
158
                throw new IllegalStateException(msg);
159
            }
160
161
            // Calculate at what time a session would have been last accessed
162
            // for it to be expired at this point.  In other words, subtract
163
            // from the current time the amount of time that a session can
164
            // be inactive before expiring.  If the session was last accessed
165
            // before this time, it is expired.
166
            long expireTimeMillis = System.currentTimeMillis() - timeout;
167
            Date expireTime = new Date(expireTimeMillis);
168
            return lastAccessTime.before(expireTime);
169
        } else {
170
            if (log.isTraceEnabled()) {
171
                log.trace("No timeout for session with id [" + getId() +
172
                        "].  Session is not considered expired.");
173
            }
174
        }
175
176
        return false;
177
    }
178
179
    public void validate() throws InvalidSessionException {
180
        //check for stopped:
181
        if (isStopped()) {
182
            //timestamp is set, so the session is considered stopped:
183
            String msg = "Session with id [" + getId() + "] has been " +
184
                    "explicitly stopped.  No further interaction under this session is " +
185
                    "allowed.";
186
            throw new StoppedSessionException(msg);
187
        }
188
189
        //check for expiration
190
        if (isTimedOut()) {
191
            expire();
192
193
            //throw an exception explaining details of why it expired:
194
            Date lastAccessTime = getLastAccessTime();
195
            long timeout = getTimeout();
196
197
            Serializable sessionId = getId();
198
199
            DateFormat df = DateFormat.getInstance();
200
            String msg = "Session with id [" + sessionId + "] has expired. " +
201
                    "Last access time: " + df.format(lastAccessTime) +
202
                    ".  Current time: " + df.format(new Date()) +
203
                    ".  Session timeout is set to " + timeout / MILLIS_PER_SECOND + " seconds (" +
204
                    timeout / MILLIS_PER_MINUTE + " minutes)";
205
            if (log.isTraceEnabled()) {
206
                log.trace(msg);
207
            }
208
            throw new ExpiredSessionException(msg);
209
        }
210
    }
211
212
    private Map<Object, Object> getAttributesLazy() {
213
        Map<Object, Object> attributes = getAttributes();
214
        if (attributes == null) {
215
            attributes = new HashMap<Object, Object>();
216
            setAttributes(attributes);
217
        }
218
        return attributes;
219
    }
220
221
    public Collection<Object> getAttributeKeys() throws InvalidSessionException {
222
        Map<Object, Object> attributes = getAttributes();
223
        if (attributes == null) {
224
            return Collections.emptySet();
225
        }
226
        return attributes.keySet();
227
    }
228
229
    public Object getAttribute(Object key) {
230
        Map<Object, Object> attributes = getAttributes();
231
        if (attributes == null) {
232
            return null;
233
        }
234
        return attributes.get(key);
235
    }
236
237
    public void setAttribute(Object key, Object value) {
238
        if (value == null) {
239
            removeAttribute(key);
240
        } else {
241
            getAttributesLazy().put(key, value);
242
        }
243
    }
244
245
    public Object removeAttribute(Object key) {
246
        Map<Object, Object> attributes = getAttributes();
247
        if (attributes == null) {
248
            return null;
249
        } else {
250
            return attributes.remove(key);
251
        }
252
    }
253
254
    /**
255
     * Returns {@code true} if the specified argument is an {@code instanceof} {@code SimpleSession} and both
256
     * {@link #getId() id}s are equal.  If the argument is a {@code SimpleSession} and either 'this' or the argument
257
     * does not yet have an ID assigned, the value of {@link #onEquals(SimpleSession) onEquals} is returned, which
258
     * does a necessary attribute-based comparison when IDs are not available.
259
     * <p/>
260
     * Do your best to ensure {@code SimpleSession} instances receive an ID very early in their lifecycle to
261
     * avoid the more expensive attributes-based comparison.
262
     *
263
     * @param obj the object to compare with this one for equality.
264
     * @return {@code true} if this object is equivalent to the specified argument, {@code false} otherwise.
265
     */
266
    @Override
267
    public boolean equals(Object obj) {
268
        if (this == obj) {
269
            return true;
270
        }
271
        if (obj instanceof SimpleSession) {
272
            SimpleSession other = (SimpleSession) obj;
273
            Serializable thisId = getId();
274
            Serializable otherId = other.getId();
275
            if (thisId != null && otherId != null) {
276
                return thisId.equals(otherId);
277
            } else {
278
                //fall back to an attribute based comparison:
279
                return onEquals(other);
280
            }
281
        }
282
        return false;
283
    }
284
285
    /**
286
     * Provides an attribute-based comparison (no ID comparison) - incurred <em>only</em> when 'this' or the
287
     * session object being compared for equality do not have a session id.
288
     *
289
     * @param ss the SimpleSession instance to compare for equality.
290
     * @return true if all the attributes, except the id, are equal to this object's attributes.
291
     * @since 1.0
292
     */
293
    protected boolean onEquals(SimpleSession ss) {
294
        return (getStartTimestamp() != null ? getStartTimestamp().equals(ss.getStartTimestamp()) : ss.getStartTimestamp() == null) &&
295
                (getStopTimestamp() != null ? getStopTimestamp().equals(ss.getStopTimestamp()) : ss.getStopTimestamp() == null) &&
296
                (getLastAccessTime() != null ? getLastAccessTime().equals(ss.getLastAccessTime()) : ss.getLastAccessTime() == null) &&
297
                (getTimeout() == ss.getTimeout()) &&
298
                (isExpired() == ss.isExpired()) &&
299
                (getHost() != null ? getHost().equals(ss.getHost()) : ss.getHost() == null) &&
300
                (getAttributes() != null ? getAttributes().equals(ss.getAttributes()) : ss.getAttributes() == null);
301
    }
302
303
    /**
304
     * Returns the hashCode.  If the {@link #getId() id} is not {@code null}, its hashcode is returned immediately.
305
     * If it is {@code null}, an attributes-based hashCode will be calculated and returned.
306
     * <p/>
307
     * Do your best to ensure {@code SimpleSession} instances receive an ID very early in their lifecycle to
308
     * avoid the more expensive attributes-based calculation.
309
     *
310
     * @return this object's hashCode
311
     * @since 1.0
312
     */
313
    @Override
314
    public int hashCode() {
315
        Serializable id = getId();
316
        if (id != null) {
317
            return id.hashCode();
318
        }
319
        int hashCode = getStartTimestamp() != null ? getStartTimestamp().hashCode() : 0;
320
        hashCode = 31 * hashCode + (getStopTimestamp() != null ? getStopTimestamp().hashCode() : 0);
321
        hashCode = 31 * hashCode + (getLastAccessTime() != null ? getLastAccessTime().hashCode() : 0);
322
        hashCode = 31 * hashCode + Long.valueOf(Math.max(getTimeout(), 0)).hashCode();
323
        hashCode = 31 * hashCode + Boolean.valueOf(isExpired()).hashCode();
324
        hashCode = 31 * hashCode + (getHost() != null ? getHost().hashCode() : 0);
325
        hashCode = 31 * hashCode + (getAttributes() != null ? getAttributes().hashCode() : 0);
326
        return hashCode;
327
    }
328
329
    /**
330
     * Returns the string representation of this SimpleSession, equal to
331
     * <code>getClass().getName() + &quot;,id=&quot; + getId()</code>.
332
     *
333
     * @return the string representation of this SimpleSession, equal to
334
     *         <code>getClass().getName() + &quot;,id=&quot; + getId()</code>.
335
     * @since 1.0
336
     */
337
    @Override
338
    public String toString() {
339
        StringBuilder sb = new StringBuilder();
340
        sb.append(getClass().getName()).append(",id=").append(getId());
341
        return sb.toString();
342
    }
343
344
    /**
345
     * Serializes this object to the specified output stream for JDK Serialization.
346
     *
347
     * @param out output stream used for Object serialization.
348
     * @throws IOException if any of this object's fields cannot be written to the stream.
349
     * @since 1.0
350
     */
351
    private void writeObject(ObjectOutputStream out) throws IOException {
352
        out.defaultWriteObject();
353
        short alteredFieldsBitMask = getAlteredFieldsBitMask();
354
        out.writeShort(alteredFieldsBitMask);
355
        if (id != null) {
356
            out.writeObject(id);
357
        }
358
        if (startTimestamp != null) {
359
            out.writeObject(startTimestamp);
360
        }
361
        if (stopTimestamp != null) {
362
            out.writeObject(stopTimestamp);
363
        }
364
        if (lastAccessTime != null) {
365
            out.writeObject(lastAccessTime);
366
        }
367
        if (timeout != 0l) {
368
            out.writeLong(timeout);
369
        }
370
        if (expired) {
371
            out.writeBoolean(expired);
372
        }
373
        if (host != null) {
374
            out.writeUTF(host);
375
        }
376
        if (!CollectionUtils.isEmpty(attributes)) {
377
            out.writeObject(attributes);
378
        }
379
    }
380
381
    /**
382
     * Reconstitutes this object based on the specified InputStream for JDK Serialization.
383
     *
384
     * @param in the input stream to use for reading data to populate this object.
385
     * @throws IOException            if the input stream cannot be used.
386
     * @throws ClassNotFoundException if a required class needed for instantiation is not available in the present JVM
387
     * @since 1.0
388
     */
389
    @SuppressWarnings({"unchecked"})
390
    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
391
        in.defaultReadObject();
392
        short bitMask = in.readShort();
393
394
        if (isFieldPresent(bitMask, ID_BIT_MASK)) {
395
            this.id = (Serializable) in.readObject();
396
        }
397
        if (isFieldPresent(bitMask, START_TIMESTAMP_BIT_MASK)) {
398
            this.startTimestamp = (Date) in.readObject();
399
        }
400
        if (isFieldPresent(bitMask, STOP_TIMESTAMP_BIT_MASK)) {
401
            this.stopTimestamp = (Date) in.readObject();
402
        }
403
        if (isFieldPresent(bitMask, LAST_ACCESS_TIME_BIT_MASK)) {
404
            this.lastAccessTime = (Date) in.readObject();
405
        }
406
        if (isFieldPresent(bitMask, TIMEOUT_BIT_MASK)) {
407
            this.timeout = in.readLong();
408
        }
409
        if (isFieldPresent(bitMask, EXPIRED_BIT_MASK)) {
410
            this.expired = in.readBoolean();
411
        }
412
        if (isFieldPresent(bitMask, HOST_BIT_MASK)) {
413
            this.host = in.readUTF();
414
        }
415
        if (isFieldPresent(bitMask, ATTRIBUTES_BIT_MASK)) {
416
            this.attributes = (Map<Object, Object>) in.readObject();
417
        }
418
    }
419
420
    /**
421
     * Returns a bit mask used during serialization indicating which fields have been serialized. Fields that have been
422
     * altered (not null and/or not retaining the class defaults) will be serialized and have 1 in their respective
423
     * index, fields that are null and/or retain class default values have 0.
424
     *
425
     * @return a bit mask used during serialization indicating which fields have been serialized.
426
     * @since 1.0
427
     */
428
    private short getAlteredFieldsBitMask() {
429
        int bitMask = 0;
430
        bitMask = id != null ? bitMask | ID_BIT_MASK : bitMask;
431
        bitMask = startTimestamp != null ? bitMask | START_TIMESTAMP_BIT_MASK : bitMask;
432
        bitMask = stopTimestamp != null ? bitMask | STOP_TIMESTAMP_BIT_MASK : bitMask;
433
        bitMask = lastAccessTime != null ? bitMask | LAST_ACCESS_TIME_BIT_MASK : bitMask;
434
        bitMask = timeout != 0l ? bitMask | TIMEOUT_BIT_MASK : bitMask;
435
        bitMask = expired ? bitMask | EXPIRED_BIT_MASK : bitMask;
436
        bitMask = host != null ? bitMask | HOST_BIT_MASK : bitMask;
437
        bitMask = !CollectionUtils.isEmpty(attributes) ? bitMask | ATTRIBUTES_BIT_MASK : bitMask;
438
        return (short) bitMask;
439
    }
440
441
    /**
442
     * Returns {@code true} if the given {@code bitMask} argument indicates that the specified field has been
443
     * serialized and therefore should be read during deserialization, {@code false} otherwise.
444
     *
445
     * @param bitMask      the aggregate bitmask for all fields that have been serialized.  Individual bits represent
446
     *                     the fields that have been serialized.  A bit set to 1 means that corresponding field has
447
     *                     been serialized, 0 means it hasn't been serialized.
448
     * @param fieldBitMask the field bit mask constant identifying which bit to inspect (corresponds to a class attribute).
449
     * @return {@code true} if the given {@code bitMask} argument indicates that the specified field has been
450
     *         serialized and therefore should be read during deserialization, {@code false} otherwise.
451
     * @since 1.0
452
     */
453
    private static boolean isFieldPresent(short bitMask, int fieldBitMask) {
454
        return (bitMask & fieldBitMask) != 0;
455
    }
456
457
}

DelegatingSession

1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
package org.apache.shiro.session.mgt;
20
21
import org.apache.shiro.session.InvalidSessionException;
22
import org.apache.shiro.session.Session;
23
24
import java.io.Serializable;
25
import java.util.Collection;
26
import java.util.Date;
27
28
/**
29
 * A DelegatingSession is a client-tier representation of a server side
30
 * {@link org.apache.shiro.session.Session Session}.
31
 * This implementation is basically a proxy to a server-side {@link NativeSessionManager NativeSessionManager},
32
 * which will return the proper results for each method call.
33
 * <p/>
34
 * <p>A <tt>DelegatingSession</tt> will cache data when appropriate to avoid a remote method invocation,
35
 * only communicating with the server when necessary.
36
 * <p/>
37
 * <p>Of course, if used in-process with a NativeSessionManager business POJO, as might be the case in a
38
 * web-based application where the web classes and server-side business pojos exist in the same
39
 * JVM, a remote method call will not be incurred.
40
 *
41
 * @since 0.1
42
 */
43
public class DelegatingSession implements Session, Serializable {
44
45
    //TODO - complete JavaDoc
46
47
    private final SessionKey key;
48
49
    //cached fields to avoid a server-side method call if out-of-process:
50
    private Date startTimestamp = null;
51
    private String host = null;
52
53
    /**
54
     * Handle to the target NativeSessionManager that will support the delegate calls.
55
     */
56
    private final transient NativeSessionManager sessionManager;
57
58
59
    public DelegatingSession(NativeSessionManager sessionManager, SessionKey key) {
60
        if (sessionManager == null) {
61
            throw new IllegalArgumentException("sessionManager argument cannot be null.");
62
        }
63
        if (key == null) {
64
            throw new IllegalArgumentException("sessionKey argument cannot be null.");
65
        }
66
        if (key.getSessionId() == null) {
67
            String msg = "The " + DelegatingSession.class.getName() + " implementation requires that the " +
68
                    "SessionKey argument returns a non-null sessionId to support the " +
69
                    "Session.getId() invocations.";
70
            throw new IllegalArgumentException(msg);
71
        }
72
        this.sessionManager = sessionManager;
73
        this.key = key;
74
    }
75
76
    /**
77
     * @see org.apache.shiro.session.Session#getId()
78
     */
79
    public Serializable getId() {
80
        return key.getSessionId();
81
    }
82
83
    /**
84
     * @see org.apache.shiro.session.Session#getStartTimestamp()
85
     */
86
    public Date getStartTimestamp() {
87
        if (startTimestamp == null) {
88
            startTimestamp = sessionManager.getStartTimestamp(key);
89
        }
90
        return startTimestamp;
91
    }
92
93
    /**
94
     * @see org.apache.shiro.session.Session#getLastAccessTime()
95
     */
96
    public Date getLastAccessTime() {
97
        //can't cache - only business pojo knows the accurate time:
98
        return sessionManager.getLastAccessTime(key);
99
    }
100
101
    public long getTimeout() throws InvalidSessionException {
102
        return sessionManager.getTimeout(key);
103
    }
104
105
    public void setTimeout(long maxIdleTimeInMillis) throws InvalidSessionException {
106
        sessionManager.setTimeout(key, maxIdleTimeInMillis);
107
    }
108
109
    public String getHost() {
110
        if (host == null) {
111
            host = sessionManager.getHost(key);
112
        }
113
        return host;
114
    }
115
116
    /**
117
     * @see org.apache.shiro.session.Session#touch()
118
     */
119
    public void touch() throws InvalidSessionException {
120
        sessionManager.touch(key);
121
    }
122
123
    /**
124
     * @see org.apache.shiro.session.Session#stop()
125
     */
126
    public void stop() throws InvalidSessionException {
127
        sessionManager.stop(key);
128
    }
129
130
    /**
131
     * @see org.apache.shiro.session.Session#getAttributeKeys
132
     */
133
    public Collection<Object> getAttributeKeys() throws InvalidSessionException {
134
        return sessionManager.getAttributeKeys(key);
135
    }
136
137
    /**
138
     * @see org.apache.shiro.session.Session#getAttribute(Object key)
139
     */
140
    public Object getAttribute(Object attributeKey) throws InvalidSessionException {
141
        return sessionManager.getAttribute(this.key, attributeKey);
142
    }
143
144
    /**
145
     * @see Session#setAttribute(Object key, Object value)
146
     */
147
    public void setAttribute(Object attributeKey, Object value) throws InvalidSessionException {
148
        if (value == null) {
149
            removeAttribute(attributeKey);
150
        } else {
151
            sessionManager.setAttribute(this.key, attributeKey, value);
152
        }
153
    }
154
155
    /**
156
     * @see Session#removeAttribute(Object key)
157
     */
158
    public Object removeAttribute(Object attributeKey) throws InvalidSessionException {
159
        return sessionManager.removeAttribute(this.key, attributeKey);
160
    }
161
}

这是个门面类,它所有的方法实现都是调用 sessionManager 的相应方法

SessionFactory

image-20191028104000531

只有一个方法: createSession()

1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one
3
 * or more contributor license agreements.  See the NOTICE file
4
 * distributed with this work for additional information
5
 * regarding copyright ownership.  The ASF licenses this file
6
 * to you under the Apache License, Version 2.0 (the
7
 * "License"); you may not use this file except in compliance
8
 * with the License.  You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing,
13
 * software distributed under the License is distributed on an
14
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
 * KIND, either express or implied.  See the License for the
16
 * specific language governing permissions and limitations
17
 * under the License.
18
 */
19
package org.apache.shiro.session.mgt;
20
21
import org.apache.shiro.session.Session;
22
23
/**
24
 * {@code SessionFactory} implementation that generates {@link SimpleSession} instances.
25
 *
26
 * @since 1.0
27
 */
28
public class SimpleSessionFactory implements SessionFactory {
29
30
    /**
31
     * Creates a new {@link SimpleSession SimpleSession} instance retaining the context's
32
     * {@link SessionContext#getHost() host} if one can be found.
33
     *
34
     * @param initData the initialization data to be used during {@link Session} creation.
35
     * @return a new {@link SimpleSession SimpleSession} instance
36
     */
37
    public Session createSession(SessionContext initData) {
38
        if (initData != null) {
39
            String host = initData.getHost();
40
            if (host != null) {
41
                return new SimpleSession(host);
42
            }
43
        }
44
        return new SimpleSession();
45
    }
46
}