• 本地服务调用


    本地服务是部署在同一个jvm中相同的模块或者不同的模块之间的服务调用。

    因各模块有自己的运行空间,拥有独立的ClassLoader,因此模块间的服务调用也会存在差异。

    模块内的服务调用,类似Spring,获取Bean的实例,并调用相关方法:

    @Service("AuthService")

    public class AuthService  extends AbstractService{

    public Data auth(@Param(value="principal",required=true)Principal principal,

    @Param(value="url",required=true)String url) throws Exception {

    User user = (User)principal;

    MenuService ms = module.getService(MenuService.class);

    Data menu = ms.findByUrl(url);

    long perm_id = menu.getLong("perm_id", 0);

    if(perm_id == 0) return new Data("authResult", true); //not protected url

    List<String> perm_ids = user.getData().get("perm_ids");

    for(String pid: perm_ids) {

    if(Long.parseLong(pid) == perm_id)

    return new Data("authResult", true);

    }

    return new Data("authResult", false);

    }

    }

    这种使用的优势:

    1、MenuService的引用非常清晰,如果后续发生重构等,也会跟着完成重构。

    2、MenuService的方法findByUrl(url)显式被调用,更易于阅读;

    缺点,只能在当前模块中调用,否则会出现ClassNotFoundException的。

    模块间的服务调用,无论是模块内部或者模块间都可以采用这种方式:

    public abstract class ServiceHelper {

    private static Map<String, Map<String, Map<String, Object>>> cache = Utils.newHashMap();

    public static Data invoke(String moduleId, String serviceId, Data request) throws Exception {

    return Application.getInstance().getModules().getModule(moduleId).invoke(serviceId, request);

    }

    }

    调用时:ServiceHelper.invoke("pas","AuthService:auth",new Data("principal",principalInstance,"url","http://localhost:8080/pas/index.shtml"));

    参数pas:是服务所在的模块

    参数AuthService:auth:服务ID和调用的服务方法,中间使用英文冒号分开

    参数Data:auth方法需要的参数

    关注红色的principal和url,这个跟参数的Param注解声明的必须是一致的,参考上面auth方法的声明。

    优势:太方便了

    不足:在可读性上存在一些缺陷,但是考虑到你正在用别人的service,这样已经很方便了,不是吗。

    实现,LocalModule中的invoke方法:

    public Data invoke(String serviceId, Data request) {

    LocalModule currentModule = ThreadContext.getContext().getModule();

    ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader();

    String sid = ThreadContext.getContext().getServiceId();

    Data req = ThreadContext.getContext().getRequest();

    Principal p = ThreadContext.getContext().getPrincipal();

    Data response = null;

    try {

    Thread.currentThread().setContextClassLoader(this.getClassLoader());

    ThreadContext.getContext().reset(this, serviceId, request, p);

    response = ModuleServiceInvoker.invoke(this, request, serviceId);

    return response;

    } finally {

    Thread.currentThread().setContextClassLoader(threadClassLoader);

    ThreadContext.getContext().reset(currentModule, sid, req, p);

    }

    }

    注意红色部分ClassLoader切换,因此可以在不同的模块间调用服务。

    框架源码:https://github.com/hifong/flying

    博客空间:http://www.cnblogs.com/hifong/

    Demo应用:https://github.com/hifong/pas

    技术QQ群:455852142

  • 相关阅读:
    12、mybatis学习——mybatis懒加载的设置
    11、mybatis学习——自定义结果映射resultMap以及关联查询
    10、mybatis学习——sqlmapper配置返回list和map结果集
    9、mybatis学习——sqlmapper配置中#{}和${}的区别
    8、mybatis学习——sqlmapper配置文件参数处理(单个参数,多个参数,命名参数)
    7、mybatis学习——mybatis基础增删改&&mybatis获取自增主键
    6、mybatis学习——mapper映射配置
    5、mybatis学习——mybatis多数据库厂商支持
    [20180927]ora-01426.txt
    [20180928]ora-01426(补充).txt
  • 原文地址:https://www.cnblogs.com/hifong/p/5440651.html
Copyright © 2020-2023  润新知