Dropwizards 中文手册

Dropwizard 核心

dropwizard核心模块提供了你创建一个应用所需的大部分。 它包括:

  • jetty,一个高性能的http服务器
  • jersey, 一个功能强大的restful web 框架
  • jackson , JVM上最好的json库
  • metrics , 一个非常棒的应用检测库
  • guava, 谷歌出品的实用库
  • logback, 继承自log4j, java 中是用最广泛的日志框架
  • hibernate validator, java bean 验证标准的参考实现。 综上,dropwizard 包含的大部分代码就是将以上所述组件像胶水一样自动连接起来。

    项目组织

    通常来说,我们建议将项目分为以下三个maven 模块: project-apiproject-clientproject-application. project-api 包含你的representations,就是展现层。project-client 通过编写一些类以及http client来为你的应用实现一个功能齐全的客户端。project-application 提供具体的应用实现,包含resources. 整个组织架构看起来像如下:

  • com.example.myapplication: ------ api:展现层 ------ cli:命令行 ------ client:客户端实现 ------ core ------ jdbi : 数据库连接类 ------ healthy :检测类 ------ resources :资源类 ------ MyApplication : 应用类 ------ MyApplicationConfiguration:注册类

Application类(应用类)

Application类是dropwizard应用的入口。每一个Application都有一个 name 属性,主要是用来作为命令行接口。在构建你的应用的时候可以添加Bundles(捆绑)和commands(命令行)到你的应用中。

Configuration(注册类)

dropwizard提供了一系列内建的注册参数。他们的详细说明见示例.
每一个Application子类都有一个类型参数:就是与之相对应的Configuration的子类。他们通常在你应用的main package 里。比如,你的user application 应该会有如下两个类:UserApplicationConfiguration, 继承自 Configuration, UserApplication , 继承自Application

. 当应用运行Configuration Commands ,比如 server 命令。Dropwizard 会解析给定的YAML 注册文件并创建一个属性相应的的注册类示例。 注意: 如果你的注册文件不是以 .yml 或 .yaml 形式结尾,Dropwizard 会以json的形式进行解析。 为了更好的管理注册文件和注册类,我们建议进行分组处理,将相关联的注册参数分进一个独立的注册类。比如,如果你的应用为了关联一个信息队列需要一系列的注册参数,我们建议新建一个 MessageQueueFactory 类:


public class MessageQueueFactory {
    @NotEmpty
    private String host;

    @Min(1)
    @Max(65535)
    private int port = 5672;

    @JsonProperty
    public String getHost() {
        return host;
    }

    @JsonProperty
    public void setHost(String host) {
        this.host = host;
    }

    @JsonProperty
    public int getPort() {
        return port;
    }

    @JsonProperty
    public void setPort(int port) {
        this.port = port;
    }

    public MessageQueueClient build(Environment environment) {
        MessageQueueClient client = new MessageQueueClient(getHost(), getPort());
        environment.lifecycle().manage(new Managed() {
            @Override
            public void start() {
            }

            @Override
            public void stop() {
                client.close();
            }
        });
        return client;
    }
}

这个例子中,工厂类自动的将 MessageQueueClient 类连接到我们 Environment的生命周期中。

同时,注册类子类也要增加相应属性,如下:

public class ExampleConfiguration extends Configuration {
    @Valid
    @NotNull
    private MessageQueueFactory messageQueue = new MessageQueueFactory();

    @JsonProperty("messageQueue")
    public MessageQueueFactory getMessageQueueFactory() {
        return messageQueue;
    }

    @JsonProperty("messageQueue")
    public void setMessageQueueFactory(MessageQueueFactory factory) {
        this.messageQueue = factory;
    }
}

这样Application 子类就可以直接用工厂类为消息队列构建一个client:

public void run(ExampleConfiguration configuration,
                Environment environment) {
    MessageQueueClient messageQueue = configuration.getMessageQueueFactory().build(environment);
}

然后,在你应用的YAML文件里,添加一个嵌套的字段:

messageQueue:
  host: mq.example.com
  port: 5673

注释部分的@NotNull,@NotEmpty,@Min,@Max,@Valid都是Dropwizard Validation的功能。如果你的YAML注册文件messageQueue.host字段没有或者是一个空字符串,Dropwizard就不会启动,输出一个错误信息描述此问题。
一旦应用解析YAML文件并构建相应的Configuration实例,Dropwizard会调用Application子类来初始化你的Environment.

注意:

当启动应用时你可以通过传递指定java系统属性的方式来覆盖配置设定。覆盖的时候必须包含前缀 dw.,后面紧跟需要被覆盖的配置设定。 举个例子,覆盖Logging level,示例如下:

java -Ddw.logging.level=DEBUG server my-config.json

就算在配置文件里没有logging.level这个属性,应用也可以启动。因为在这里会自动添加。 可以以数组的形式进行覆盖:

java -Ddw.server.applicationConnectors[0].port=9090 server my-config.json

可以以map映射的方式来覆盖:

java -Ddw.database.properties.hibernate.hbm2ddl.auto=none server my-config.json

如果配置设定是一个String数组,你也可以用','作为分隔符。比如,myapp.myserver.hosts 这个配置设定是一个String数组,你可以通过如下方式覆盖:

java -Ddw.myapp.myserver.hosts=server1,server2,server3 server my-config.json

如果数组元素里面包含',',你可以用加引号的方式代替。 数组覆盖的形式必须是简单的字符串数组。而且,覆盖的数组必须在配置文件中存在。如果不存在的话,这套数组覆盖机制是不适用的。如果在不存在或不是数组的情况下使用,那么包含','都会看作一个大的字符串而不是数组。

Environment variables 环境变量

dropwizard-configuration 模块还提供了以下一种功能,你可以通过 SubstitutingSourceProviderEnvironmentVariableSubstitutor 用环境变量的值替换配置里面的设定。

public class MyApplication extends Application<MyConfiguration> {
    // [...]
    @Override
    public void initialize(Bootstrap<MyConfiguration> bootstrap) {
        // Enable variable substitution with environment variables
        bootstrap.setConfigurationSourceProvider(
                new SubstitutingSourceProvider(bootstrap.getConfigurationSourceProvider(),
                                                   new EnvironmentVariableSubstitutor(false)
                )
        );

    }

    // [...]
}

替换的配置文件里的设定必须是明确指出,而且遵守Apache Commons Lang library 里的StrSubstitutor规则。

mySetting: ${DW_MY_SETTING}
defaultSetting: ${DW_DEFAULT_SETTING:-default value}

以下一段没明白,直接引用

In general SubstitutingSourceProvider isn’t restricted to substitute environment variables but can be used to replace variables in the configuration source with arbitrary values by passing a custom StrSubstitutor implementation.

SSL

Dropwizard默认是内嵌支持SSL的。你只需提供你的java密钥库(本文不做讨论,keytool 是相关的命令。)Dropwizard example project此项目包含一个测试的密钥库。

server:
  applicationConnectors:
    - type: https
      port: 8443
      keyStorePath: example.keystore
      keyStorePassword: example
      validateCerts: false

Bootstrapping

在你的dropwizard应用提供给你一个命令行的接口之前,无论是解析配置文件,还是运行服务,都必须首先经过一个Bootstrapping阶段。这个阶段相当于是你的Application 子类中的initialize方法。你可以添加Bundles,Commands或者注册Jackson模块,允许添加类型,作为你的配置类的一部分。

Environments

一个dropwizard environment 包含了所有的 Resources,servlets,fiflters,Healthy Checks,Jersey providers,Managed Objects,Tasks,以及你的应用提供的Jersey属性。