多线程中自定义线程池与shiro导致的权限错乱问题解决

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();
    }
}
posted @ 2024-07-12 08:28  阿灿呀  阅读(168)  评论(0)    收藏  举报