Creates a new {@code SubjectRunnable} that, when executed, will execute the target {@code delegate}, but guarantees that it will run associated with the specified {@code Subject}.
Creates a new {@code SubjectRunnable} that, when executed, will perform thread state {@link ThreadState#bind binding} and guaranteed {@link ThreadState#restore restoration} before and after the {@link Runnable Runnable}'s execution, respectively.
Simply calls the target {@link Runnable Runnable}'s {@link Runnable#run run()} method.
{@link ThreadState#bind Bind}s the Subject thread state, executes the target {@code Runnable} and then guarantees the previous thread state's {@link ThreadState#restore restoration}: <pre> try { threadState.{@link ThreadState#bind bind()}; {@link #doRun doRun}(targetRunnable); } finally { threadState.{@link ThreadState#restore restore()} } </pre>
A {@code SubjectRunnable} ensures that a target/delegate {@link Runnable Runnable} will execute such that any call to {@code SecurityUtils.}{@link hunt.shiro.SecurityUtils#getSubject() getSubject()} during the {@code Runnable}'s execution will return the associated {@code Subject} instance. The {@code SubjectRunnable} instance can be run on any thread (the current thread or asynchronously on another thread) and the {@code SecurityUtils.getSubject()} call will still work properly. This implementation also guarantees that Shiro's thread state will be identical before and after execution to ensure threads remain clean in any thread-pooled environment. <p/> When instances of this class {@link Runnable#run() run()}, the following occurs: <ol> <li>The Subject and any of its associated thread state is first bound to the thread that executes the {@code Runnable}.</li> <li>The delegate/target {@code Runnable} is {@link #doRun(Runnable) run}</li> <li>Any previous thread state that might have existed before the {@code Subject} was bound is fully restored</li> </ol> <p/>
<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#execute(Runnable) execute} or {@code Subject.}{@link Subject#associateWith(Runnable) associateWith} methods, which transparently perform the necessary association logic. <p/> An even more convenient alternative is to use a {@link hunt.shiro.concurrent.SubjectAwareExecutor SubjectAwareExecutor}, which transparently uses instances of this class but does not require referencing Shiro's API at all.
@see Subject#associateWith(Runnable) @see hunt.shiro.concurrent.SubjectAwareExecutor SubjectAwareExecutor