class AbstractDtpAdapter extends OnceApplicationContextEventListener implements DtpAdapter {

    private static final Equator EQUATOR = new GetterBaseEquator();

    protected final Map<String, ExecutorWrapper> executors = Maps.newHashMap();

    @Override
    protected void onContextRefreshedEvent(ContextRefreshedEvent event) {
        try {
            DtpProperties dtpProperties = ApplicationContextHolder.getBean(DtpProperties.class);
            initialize();
            afterInitialize();
            refresh(dtpProperties);
            log.info("DynamicTp adapter, {} init end, executors: {}", getTpPrefix(), executors);
        } catch (Throwable e) {
            log.error("DynamicTp adapter, {} init failed.", getTpPrefix(), e);
        }
    }

    protected void initialize() {
    }

    protected void afterInitialize() {
        getExecutorWrappers().forEach((k, v) -> AwareManager.register(v));
    }

    @Override
    public Map<String, ExecutorWrapper> getExecutorWrappers() {
        return executors;
    }

    /**
     * Get multi thread pool stats.
     *
     * @return thead pools stats
     */
    @Override
    public List<ThreadPoolStats> getMultiPoolStats() {
        val executorWrappers = getExecutorWrappers();
        if (MapUtils.isEmpty(executorWrappers)) {
            return Collections.emptyList();
        }

        List<ThreadPoolStats> threadPoolStats = Lists.newArrayList();
        executorWrappers.forEach((k, v) -> threadPoolStats.add(ExecutorConverter.toMetrics(v)));
        return threadPoolStats;
    }

    public void refresh(List<TpExecutorProps> propsList, List<NotifyPlatform> platforms) {
        val executorWrappers = getExecutorWrappers();
        if (CollectionUtils.isEmpty(propsList) || MapUtils.isEmpty(executorWrappers)) {
            return;
        }

        val tmpMap = StreamUtil.toMap(propsList, TpExecutorProps::getThreadPoolName);
        executorWrappers.forEach((k, v) -> refresh(v, platforms, tmpMap.get(k)));
    }

    public void refresh(ExecutorWrapper executorWrapper, List<NotifyPlatform> platforms, TpExecutorProps props) {<FILL_FUNCTION_BODY>}

    protected TpMainFields getTpMainFields(ExecutorWrapper executorWrapper, TpExecutorProps props) {
        return ExecutorConverter.toMainFields(executorWrapper);
    }

    /**
     * Get tp prefix.
     * @return tp prefix
     */
    protected abstract String getTpPrefix();

    protected void enhanceOriginExecutor(String tpName, ThreadPoolExecutor executor, String fieldName, Object targetObj) {
        ThreadPoolExecutorProxy proxy = new ThreadPoolExecutorProxy(executor);
        try {
            ReflectionUtil.setFieldValue(fieldName, targetObj, proxy);
            putAndFinalize(tpName, executor, proxy);
        } catch (IllegalAccessException e) {
            log.error("DynamicTp adapter, enhance {} failed.", tpName, e);
        }
    }

    protected void putAndFinalize(String tpName, ExecutorService origin, Executor targetForWrapper) {
        executors.put(tpName, new ExecutorWrapper(tpName, targetForWrapper));
        shutdownOriginalExecutor(origin);
    }

    protected void shutdownOriginalExecutor(ExecutorService executor) {
        shutdownGracefulAsync(executor, getTpPrefix(), 5);
    }

    protected void doRefresh(ExecutorWrapper executorWrapper,
                             List<NotifyPlatform> platforms,
                             TpExecutorProps props) {

        val executor = executorWrapper.getExecutor();
        doRefreshPoolSize(executor, props);
        if (!Objects.equals(executor.getKeepAliveTime(props.getUnit()), props.getKeepAliveTime())) {
            executor.setKeepAliveTime(props.getKeepAliveTime(), props.getUnit());
        }
        if (StringUtils.isNotBlank(props.getThreadPoolAliasName())) {
            executorWrapper.setThreadPoolAliasName(props.getThreadPoolAliasName());
        }
        List<TaskWrapper> taskWrappers = TaskWrappers.getInstance().getByNames(props.getTaskWrapperNames());
        executorWrapper.setTaskWrappers(taskWrappers);

        // update notify items
        updateNotifyInfo(executorWrapper, props, platforms);
        // update aware related
        AwareManager.refresh(executorWrapper, props);
    }

    private void doRefreshPoolSize(ExecutorAdapter<?> executor, TpExecutorProps props) {
        if (props.getMaximumPoolSize() >= executor.getMaximumPoolSize()) {
            if (!Objects.equals(props.getMaximumPoolSize(), executor.getMaximumPoolSize())) {
                executor.setMaximumPoolSize(props.getMaximumPoolSize());
            }
            if (!Objects.equals(props.getCorePoolSize(), executor.getCorePoolSize())) {
                executor.setCorePoolSize(props.getCorePoolSize());
            }
            return;
        }

        if (!Objects.equals(props.getCorePoolSize(), executor.getCorePoolSize())) {
            executor.setCorePoolSize(props.getCorePoolSize());
        }
        if (!Objects.equals(props.getMaximumPoolSize(), executor.getMaximumPoolSize())) {
            executor.setMaximumPoolSize(props.getMaximumPoolSize());
        }
    }
}


        if (Objects.isNull(props) || Objects.isNull(executorWrapper) || containsInvalidParams(props, log)) {
            return;
        }

        TpMainFields oldFields = getTpMainFields(executorWrapper, props);
        doRefresh(executorWrapper, platforms, props);
        TpMainFields newFields = getTpMainFields(executorWrapper, props);
        if (oldFields.equals(newFields)) {
            log.debug("DynamicTp adapter, main properties of [{}] have not changed.",
                    executorWrapper.getThreadPoolName());
            return;
        }

        List<FieldInfo> diffFields = EQUATOR.getDiffFields(oldFields, newFields);
        List<String> diffKeys = diffFields.stream().map(FieldInfo::getFieldName).collect(toList());
        NoticeManager.tryNoticeAsync(executorWrapper, oldFields, diffKeys);
        log.info("DynamicTp adapter, [{}] refreshed end, changed keys: {}, corePoolSize: [{}], "
                        + "maxPoolSize: [{}], keepAliveTime: [{}]",
                executorWrapper.getThreadPoolName(), diffKeys,
                String.format(PROPERTIES_CHANGE_SHOW_STYLE, oldFields.getCorePoolSize(), newFields.getCorePoolSize()),
                String.format(PROPERTIES_CHANGE_SHOW_STYLE, oldFields.getMaxPoolSize(), newFields.getMaxPoolSize()),
                String.format(PROPERTIES_CHANGE_SHOW_STYLE, oldFields.getKeepAliveTime(), newFields.getKeepAliveTime()));
    
<methods>public void onApplicationEvent(ApplicationEvent) ,public final void setApplicationContext(ApplicationContext) <variables>private ApplicationContext applicationContext