Latke 代码阅读-1 Latke.java

本贴最后更新于 2751 天前,其中的信息可能已经天翻地覆

大致的代码结构:

  • java
  • b3log
    • cache,cron,event,image,intercept,ioc
    • logging,mail,model,plugin,remote,repository
    • service,servlet,taskqueue,thread,urlfetch,user,util
    • Latkes.java
    • Keys.java,Runtimetabase.java,RuntimeEnv.java,RuntimeMode.java
  • json
  • weborganic
  • resources
    • beans.xml

Latkes.java 下面那一行涉及的代码基本没有逻辑,全是枚举或者常量值的定义,想来无可研究。
开始的字段定义继续忽略,首先是静态代码块(删去了 LOGGER):

static {
        try {
            final InputStream resourceAsStream = Latkes.class.getResourceAsStream("/latke.properties");
            if (null != resourceAsStream) {
                LATKE_PROPS.load(resourceAsStream);
            }
        } catch (final Exception e) {
            throw new RuntimeException("Not found latke.properties");
        }
        try {
            final InputStream resourceAsStream = Latkes.class.getResourceAsStream("/local.properties");
            if (null != resourceAsStream) {
                LOCAL_PROPS.load(resourceAsStream);
            }
        } catch (final Exception e) {
        }
        try {
            final InputStream resourceAsStream = Latkes.class.getResourceAsStream("/remote.properties");
            if (null != resourceAsStream) {
                REMOTE_PROPS.load(resourceAsStream);
            }
        } catch (final Exception e) {
        }
    }

需要注意的点:

  • 静态代码块,意味着这段代码将在类实例化的时候首先得到执行
  • Latkes.class.getResourceAsStream,这个用法不知是什么
  • LATKE_PROPS 是 Properties 类型

接下来大部分是从 properties 文件里获取配置的方法,不一一列举,如:

public static String getStaticResourceVersion() {
        //如果没有值,则从配置文件中读取,否则直接返回
        if (null == staticResourceVersion) {
            staticResourceVersion = LATKE_PROPS.getProperty("staticResourceVersion");
            //如果没有读取到,则赋予默认值
            if (null == staticResourceVersion) {
                staticResourceVersion = startupTimeMillis;
            }
        }
        return staticResourceVersion;
    }

初始化运行环境,Starter 类会调用该方法:

public static void initRuntimeEnv() {
        if (null != runtimeEnv) {
            return;
        }
        final String runtimeEnvValue = LATKE_PROPS.getProperty("runtimeEnv"); //latke.properties
        if (null != runtimeEnvValue) {
            //如果不为空,说明配置里有设置,读取设置
            runtimeEnv = RuntimeEnv.valueOf(runtimeEnvValue);
        }
        //配置为空,设置为-本地
        runtimeEnv = RuntimeEnv.LOCAL;
        //获取设置运行模式
        if (null == runtimeMode) {
            final String runtimeModeValue = LATKE_PROPS.getProperty("runtimeMode");
            if (null != runtimeModeValue) {
                runtimeMode = RuntimeMode.valueOf(runtimeModeValue);
            } else {
                runtimeMode = RuntimeMode.PRODUCTION;
            }
        }
        if (RuntimeEnv.LOCAL == runtimeEnv) {
            // Read local database configurations
            final RuntimeDatabase runtimeDatabase = getRuntimeDatabase();
            //local.properties
            if (RuntimeDatabase.H2 == runtimeDatabase) {
                final String newTCPServer = Latkes.getLocalProperty("newTCPServer");
                if ("true".equals(newTCPServer)) {
                    final String jdbcURL = Latkes.getLocalProperty("jdbc.URL");
                    if (Strings.isEmptyOrNull(jdbcURL)) {
                        throw new IllegalStateException("The jdbc.URL in local.properties is required");
                    }
                    final String[] parts = jdbcURL.split(":");
                    if (parts.length != Integer.valueOf("5")/* CheckStyle.... */) {
                        throw new IllegalStateException("jdbc.URL should like [jdbc:h2:tcp://localhost:8250/~/] (the port part is required)");
                    }
                    String port = parts[parts.length - 1];
                    port = StringUtils.substringBefore(port, "/");
                    try {
                        h2 = org.h2.tools.Server.createTcpServer(new String[]{"-tcpPort", port, "-tcpAllowOthers"}).start();
                    } catch (final SQLException e) {
                        final String msg = "H2 TCP server create failed";
                        throw new IllegalStateException(msg);
                    }
                }
            }
        }
        locale = new Locale("en_US");
    }
  • 这段代码中包含了当数据库是 H2 时的处理,大概时使用该数据库时要自己做的事情吧,毕竟是纯 Java 库,想来不必深究,其文档应该有说明。
  • Locale 类的作用意义不明。

关闭 Latke

public static void shutdown() {
        try {
            if (RuntimeEnv.LOCAL != getRuntimeEnv()) {
                return;
            }
            //关闭数据库连接池
            Connections.shutdownConnectionPool();
            final RuntimeDatabase runtimeDatabase = getRuntimeDatabase();
            switch (runtimeDatabase) {
                case H2:
                    final String newTCPServer = Latkes.getLocalProperty("newTCPServer");
                    if ("true".equals(newTCPServer)) {
                        h2.stop();
                        h2.shutdown();
                    }
                    break;
                default:
            }
            //关闭定时任务
            CronService.shutdown();
           //关闭执行的线程
            LocalThreadService.EXECUTOR_SERVICE.shutdown();
        } catch (final Exception e) {
        }
        //停止应用生命周期
        Lifecycle.endApplication();
        // This manually deregisters JDBC driver, which prevents Tomcat from complaining about memory leaks
        //注销数据库连接驱动
        final Enumeration<Driver> drivers = DriverManager.getDrivers();
        while (drivers.hasMoreElements()) {
            final Driver driver = drivers.nextElement();
            try {
                DriverManager.deregisterDriver(driver);
            } catch (final SQLException e) {
            }
        }
    }
  • Connections, CronService, LocalThreadService, Lifecycle 均为 b3log 包下的类,此时暂不做进一步研究。
  • Driver 为 java.sql 包下的类。

加载皮肤,这个看似跟 MVC 无关的内容,放在这里,有点琢磨不透,可能是因为预先想到了由不同的皮肤,而在公共的框架上提供了支持吧:

public static void loadSkin(final String skinDirName) {
        final ServletContext servletContext = AbstractServletListener.getServletContext();
        Templates.MAIN_CFG.setServletContextForTemplateLoading(servletContext, "skins/" + skinDirName);
        Latkes.setTimeZone("Asia/Shanghai");
}
  • AbstractServletListener, Templates 为 b3log 的类,暂不详查
  • ServletContext 有什么特殊的地方?

获取皮肤名称:

public static String getSkinName(final String skinDirName) {
        try {
            final Properties ret = new Properties();
            final File file = getWebFile("/skins/" + skinDirName + "/skin.properties");
            ret.load(new FileInputStream(file));
            return ret.getProperty("name");
        } catch (final Exception e) {
            return null;
        }
    }
public static File getWebFile(final String path) {
        final ServletContext servletContext = AbstractServletListener.getServletContext();
        File ret;
        try {
            final URL resource = servletContext.getResource(path);
            if (null == resource) {
                return null;
            }
            ret = FileUtils.toFile(resource);
            if (null == ret) {
                final File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                ret = new File(tempdir.getPath() + path);
                FileUtils.copyURLToFile(resource, ret);
                ret.deleteOnExit();
            }
            return ret;
        } catch (final Exception e) {
            return null;
        }
    }
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    70 引用 • 532 回帖 • 712 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    396 引用 • 3416 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3168 引用 • 8207 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
ZephyrJung
一切有为法,如梦幻泡影,如露亦如电,应作如是观 北京

推荐标签 标签

  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    9 引用 • 32 回帖 • 164 关注
  • PHP

    PHP(Hypertext Preprocessor)是一种开源脚本语言。语法吸收了 C 语言、 Java 和 Perl 的特点,主要适用于 Web 开发领域,据说是世界上最好的编程语言。

    164 引用 • 407 回帖 • 525 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    330 引用 • 614 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 383 回帖 • 4 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 5 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 22 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    103 引用 • 294 回帖
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖 • 1 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 442 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    103 引用 • 126 回帖 • 446 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    122 引用 • 73 回帖
  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 625 关注
  • SMTP

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。

    4 引用 • 18 回帖 • 590 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    16 引用 • 53 回帖 • 123 关注
  • Angular

    AngularAngularJS 的新版本。

    26 引用 • 66 回帖 • 511 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    14 引用 • 7 回帖
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    180 引用 • 447 回帖
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    76 引用 • 37 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    75 引用 • 146 回帖
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    140 引用 • 441 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 3 关注
  • 创造

    你创造的作品可能会帮助到很多人,如果是开源项目的话就更赞了!

    172 引用 • 990 回帖
  • wolai

    我来 wolai:不仅仅是未来的云端笔记!

    1 引用 • 11 回帖 • 2 关注
  • 微信

    腾讯公司 2011 年 1 月 21 日推出的一款手机通讯软件。用户可以通过摇一摇、搜索号码、扫描二维码等添加好友和关注公众平台,同时可以将自己看到的精彩内容分享到微信朋友圈。

    129 引用 • 793 回帖
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    492 引用 • 1383 回帖 • 374 关注