月度归档: 2015 年 3 月

  • Java web容器中load-on-startup

    昨天一同事提到load-on-startup的问题,虽然知道它在标准中有提到,但是具体的细节又有点记不清楚了。

    刚才想到看了一下JSR 315: JavaTM Servlet 3.0 Specification。

    load-on-startup的作用

    load-on-startup是servlet tag下的一个值。它告诉容器加载顺序,如果不声明这个值那么容器只会在它认为需要的时候才加载它。

    这样有时会出现一个问题,如果Servlet启动时会初始化数据库连接或者加载其他信息,如果这些耗时较长的处理不在容器启动时完成,那就会在容器认为必要时加载Servlet是完成,也就是说会出现响应问题。

    所以有load-on-startup这个设置来允许你指定servlet需要在部署到容器时就加载。

    load-on-startup的值

    load-on-startup的应该是数字,有时会出现以下几种情况:

    • 如果两个Servlet的load-on-startup的值相同,那么加载顺序是在web.xml中的声明顺序。
    • 如果值为零或者负数,那么在需要时才加载。
    • 如果没有,那么加载由容器决定。
    …
  • 共享常用的Gradle配置片段

    Gradle灵活而强大,而且自定义简单,会Groovy用Groovy,不会或者不想学的直接写Java也可以。

    对于build.gradle而言,简单的项目还好,复杂项目这个配置就有点长了。

    虽然可以通过将Gradle Script抽成单个文件的方式来让配置更清晰,但是这样并没有做到常用配置的共享。

    因为很多配置其实是多个项目可以共用的,比如idea相关配置。

    分割配置

    当build.gradle文件越发繁琐的时候,最简单直接的方法就是将其拆分,比如idea相关配置可以拆分到 gradle目录中的idea.gradle文件中。

    apply plugin:'idea'
    
    idea {
    module {
    inheritOutputDirs =false
    outputDir =file("$buildDir/classes/main/")
    }
    
    project {
    ipr {
    withXml { provider ->
    def node = provider.asNode()
    node.component.find { it.'@name' =='VcsDirectoryMappings' }?.mapping[0].'@vcs' ='Git'
    }
    }
    }
    
    …
  • 使用Gradle下载phantomjs

    对于Web应用开发,测试中有一个很重要的测试是Functional Test(或者叫Integration Test)。

    Functional Test除了需要相关的库以外还需要一个Driver,可以是Chrome,Firefox等等。

    因为并不是每一个开发机器或者CI服务器都有浏览器的,所以保证测试的可用性是相当重要的。

    常用的方法是将浏览器提前下载,放置在项目目录中,纳入版本管理。这样测试的运行就可以直接使用。

    但是这种方法有两个问题:

    • 将大量文件纳入了版本管理中
    • 对于不同平台还需要下载不同平台的Driver

    其实还有一个办法就是让构建工具自动下载,下载的时候可以根据平台来下载指定版本。这样即提升了易用性,也降低了切换难度。

    这里以phantomjs为例,来看看怎么让Gradle去下载平台相关的phantomjs。

    首先明确phantomjs的下载地址,在bitbucket上,https://bitbucket.org/ariya/phantomjs/downloads。

    文件名是phantomjs+版本号+平台。

    首先对于平台的判断使用commons-io库来操作。

    import org.apache.tools.ant.taskdefs.condition.Os
    
    buildscript {
    repositories {
    jcenter()
    }
    dependencies {
    classpath"commons-io:commons-io:2.+"
    }
    }

    判断代码如下:

    def osFilenamePart
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
    osFilenamePart ="windows.zip"
    }elseif (Os.isFamily(Os.FAMILY_MAC)) 
    …