How are Spring objects represented at runtime?

后端 未结 4 1054
无人及你
无人及你 2020-12-09 04:58

I have an app that uses the \"task:scheduler\" and \"task:scheduled-tasks\" elements (the latter containing \"task:scheduled\" elements). This is all working fine.

4条回答
  •  伪装坚强ぢ
    2020-12-09 05:29

    I have a snippet for pre spring 4.2 since it is still sitting at release candidate level.

    The scheduledFuture interface is implemented by every runnable element in the BlockingQueue.

            Map schedulers = applicationContext
                    .getBeansOfType(ThreadPoolTaskScheduler.class);
            for (ThreadPoolTaskScheduler scheduler : schedulers.values()) {
                ScheduledExecutorService exec = scheduler.getScheduledExecutor();
                ScheduledThreadPoolExecutor poolExec = scheduler
                        .getScheduledThreadPoolExecutor();
                BlockingQueue queue = poolExec.getQueue();
                Iterator iter = queue.iterator();
                while (iter.hasNext()) {
                    ScheduledFuture future = (ScheduledFuture) iter.next();
                    future.getDelay(TimeUnit.MINUTES);
                Runnable job = iter.next();
                logger.debug(MessageFormat.format(":: Task Class is {0}", JobDiscoverer.findRealTask(job)));
                }
    

    Heres a reflective way to get information about which job class is in the pool as threadPoolNamePrefix didn't return a distinct name for me:

    public class JobDiscoverer {
        private final static Field syncInFutureTask;
        private final static Field callableInFutureTask;
        private static final Class adapterClass;
        private static final Field runnableInAdapter;
        private static Field reschedulingRunnable;
        private static Field targetScheduledMethod;
    
        static {
            try {
    
                reschedulingRunnable = Class
                        .forName(
                                "org.springframework.scheduling.support.DelegatingErrorHandlingRunnable")
                        .getDeclaredField("delegate");
                reschedulingRunnable.setAccessible(true);
    
                targetScheduledMethod = Class
                        .forName(
                                "org.springframework.scheduling.support.ScheduledMethodRunnable")
                        .getDeclaredField("target");
                targetScheduledMethod.setAccessible(true);
                callableInFutureTask = Class.forName(
                        "java.util.concurrent.FutureTask$Sync").getDeclaredField(
                        "callable");
                callableInFutureTask.setAccessible(true);
                syncInFutureTask = FutureTask.class.getDeclaredField("sync");
                syncInFutureTask.setAccessible(true);
    
                adapterClass = Executors.callable(new Runnable() {
                    public void run() {
                    }
                }).getClass();
                runnableInAdapter = adapterClass.getDeclaredField("task");
                runnableInAdapter.setAccessible(true);
            } catch (NoSuchFieldException e) {
                throw new ExceptionInInitializerError(e);
            } catch (SecurityException e) {
                throw new PiaRuntimeException(e);
            } catch (ClassNotFoundException e) {
                throw new PiaRuntimeException(e);
            }
        }
    
        public static Object findRealTask(Runnable task) {
            if (task instanceof FutureTask) {
                try {
                    Object syncAble = syncInFutureTask.get(task);
                    Object callable = callableInFutureTask.get(syncAble);
                    if (adapterClass.isInstance(callable)) {
                        Object reschedulable = runnableInAdapter.get(callable);
                        Object targetable = reschedulingRunnable.get(reschedulable);
                        return targetScheduledMethod.get(targetable);
                    } else {
                        return callable;
                    }
                } catch (IllegalAccessException e) {
                    throw new IllegalStateException(e);
                }
            }
            throw new ClassCastException("Not a FutureTask");
        }
    

提交回复
热议问题