多執行緒中自定義執行緒池與shiro導致的許可權錯亂問題解決

阿灿呀發表於2024-07-12
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;

import java.util.concurrent.*;

public class ShiroAwareThreadPoolExecutor extends ThreadPoolExecutor {
    public ShiroAwareThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
                                        TimeUnit unit, BlockingQueue<Runnable> workQueue,
                                        ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    @Override
    public void execute(Runnable command) {
        super.execute(wrap(command, ThreadContext.getSubject()));
    }

    private Runnable wrap(final Runnable task, final Subject subject) {
        return () -> {
            try {
                ThreadContext.bind(subject);
                task.run();
            } finally {
                ThreadContext.unbindSubject();
                ThreadContext.unbindSecurityManager();
            }
        };
    }
}

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // 建立自定義執行緒池
        ExecutorService threadPool = new ShiroAwareThreadPoolExecutor(
                10, 50, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>(100),
                Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()
        );

        // 提交任務到執行緒池
        threadPool.submit(() -> {
            System.out.println("執行任務: " + Thread.currentThread().getName());
            // 執行需要 Shiro SecurityManager 的操作
            // 注意:這裡需要確保 Shiro 已經正確初始化
            System.out.println("當前使用者: " + SecurityUtils.getSubject().getPrincipal());
        });

        // 關閉執行緒池
        threadPool.shutdown();
    }
}

相關文章