A {@code SubjectCallable} associates a {@link Subject Subject} with a target/delegate
{@link Callable Callable} to ensure proper {@code Subject} thread-state management when the {@code Callable} executes.
This ensures that any calls to {@code SecurityUtils.}{@link hunt.shiro.SecurityUtils#getSubject() getSubject()}
during the target {@code Callable}'s execution still work correctly even if the {@code Callable} executes on a
different thread than the one that created it. This allows {@code Subject} access during asynchronous operations.
<p/>
When instances of this class execute (typically via a {@link java.util.concurrent.ExecutorService ExecutorService}),
the following occurs:
<ol>
<li>The specified Subject any of its associated thread state is first bound to the thread that executes the
{@code Callable}.</li>
<li>The delegate/target {@code Callable} is {@link java.util.concurrent.Callable#call() executed}</li>
<li>The previous thread state that might have existed before the {@code Subject} was bound is fully restored</li>
</ol>
<p/>
This behavior ensures that the thread that executes this {@code Callable}, which is often a different thread than
the one that created the instance, retains a {@code Subject} to support {@code SecurityUtils.getSubject()}
invocations. It also guarantees that the running thread remains 'clean' in any thread-pooled environments.
<h3>Usage</h3>
This is typically considered a support class and is not often directly referenced. Most people prefer to use
the {@code Subject.}{@link Subject#associateWith(Callable) associateWith} method, which will automatically return
an instance of this class.
<p/>
An even more convenient alternative is to use a
{@link hunt.shiro.concurrent.SubjectAwareExecutorService SubjectAwareExecutorService}, which
transparently uses instances of this class.
A {@code SubjectCallable} associates a {@link Subject Subject} with a target/delegate {@link Callable Callable} to ensure proper {@code Subject} thread-state management when the {@code Callable} executes. This ensures that any calls to {@code SecurityUtils.}{@link hunt.shiro.SecurityUtils#getSubject() getSubject()} during the target {@code Callable}'s execution still work correctly even if the {@code Callable} executes on a different thread than the one that created it. This allows {@code Subject} access during asynchronous operations. <p/> When instances of this class execute (typically via a {@link java.util.concurrent.ExecutorService ExecutorService}), the following occurs: <ol> <li>The specified Subject any of its associated thread state is first bound to the thread that executes the {@code Callable}.</li> <li>The delegate/target {@code Callable} is {@link java.util.concurrent.Callable#call() executed}</li> <li>The previous thread state that might have existed before the {@code Subject} was bound is fully restored</li> </ol> <p/> This behavior ensures that the thread that executes this {@code Callable}, which is often a different thread than the one that created the instance, retains a {@code Subject} to support {@code SecurityUtils.getSubject()} invocations. It also guarantees that the running thread remains 'clean' in any thread-pooled environments.
<h3>Usage</h3>
This is typically considered a support class and is not often directly referenced. Most people prefer to use the {@code Subject.}{@link Subject#associateWith(Callable) associateWith} method, which will automatically return an instance of this class. <p/> An even more convenient alternative is to use a {@link hunt.shiro.concurrent.SubjectAwareExecutorService SubjectAwareExecutorService}, which transparently uses instances of this class.
@see Subject#associateWith(Callable) @see hunt.shiro.concurrent.SubjectAwareExecutorService SubjectAwareExecutorService