Jarslink源码解析-----抽象化的“Action”

最后我们来说一下我个人理解的JArslink的设计精髓-----“Action”

首先我们来看一下,SpringModule中的一段代码

private <T> Map<String, T> scanActions(ApplicationContext applicationContext, Class<T> type,
                                           Function<T, String> keyFunction) {
        Map<String, T> actions = Maps.newHashMap();
        //find Action in module
        for (T action : applicationContext.getBeansOfType(type).values()) {
            String actionName = keyFunction.apply(action);
            if (isBlank(actionName)) {
                throw new ModuleRuntimeException("JarsLink scanActions actionName is null");
            }
            String key = actionName.toUpperCase(Locale.CHINESE);
            checkState(!actions.containsKey(key), "Duplicated action %s found by: %s",
                    type.getSimpleName(), key);
            if (LOGGER.isInfoEnabled()) {
                LOGGER.info("JarsLink Scan action: {}: bean: {}", key, action);
            }
            actions.put(key, action);
        }
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("JarsLink Scan actions finish: {}", ToStringBuilder.reflectionToString(actions));
        }
        return actions;
    }

    @Override
    public Map<String, Action> getActions() {
        return actions;
    }

    @Override
    public <R, T> Action<R, T> getAction(String actionName) {
        checkNotNull(actionName, "actionName is null");
        Action action = actions.get(actionName.toUpperCase());
        checkNotNull(action, "find action is null,actionName=" + actionName);
        return action;
    }

    @Override
    public <R, T> T doAction(String actionName, R actionRequest) {
        checkNotNull(actionName, "actionName is null");
        checkNotNull(actionRequest, "actionRequest is null");
        return (T) doActionWithinModuleClassLoader(getAction(actionName), actionRequest);
    }

我们看到上面的代码大量使用了泛型,我们在实际应用中可以将其替换为我们实际应用中的某个特定的类,该类需要通过spring管理,在上下文中找到指定的该bean,将其和每个模块绑定。

protected <R, T> T doActionWithinModuleClassLoader(Action<R, T> action, R actionRequest) {
        checkNotNull(action, "action is null");
        checkNotNull(actionRequest, "actionRequest is null");
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        try {
            ClassLoader moduleClassLoader = action.getClass().getClassLoader();
            Thread.currentThread().setContextClassLoader(moduleClassLoader);
            return action.execute(actionRequest);
        } catch (Exception e) {
            LOGGER.error("调用模块出现异常,action=" + action, e);
            throw new ModuleRuntimeException("doActionWithinModuleClassLoader has error,action=" + action, e);
        } finally {
            Thread.currentThread().setContextClassLoader(classLoader);
        }
    }

我们可以看到,jarslinjk为我们提供的调用方法思路其实就是根据模块找到对应的Action对象,通过对象获取到当前模块的ClassLoader,调用Action的方法即可,其实我们可以借助这个思路,在实际应用中通过jarslink这种方式调用其实是很不方便的,大体思路就是我们将项目中的所有需要暴漏出的接口类通过一种方式注册为Action即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值