Bootique初探
介绍
Bootque改进了无容器应用启动的现有技术。它使你可以编写看起来像命令一样并由模块组成的Java应用。号称要比SpringBoot快10倍以上。今天我就来试一试它。Bootique.io是项目的官方站点。
HelloWorld [1]
-
创建项目
zzw:challenge zzw$mkdir boonique_fist_attempt zzw:challenge zzw$cd boonique_first_attempt zzw:boonique_fist_attempt zzw$mkdir -p src/main/java/com/wonderingwall/ -
创建pom.xml
zzw:boonique_fist_attempt zzw$ vi pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>io.bootique.parent</groupId> <artifactId>bootique-parent</artifactId> <version>0.13</version> </parent> <groupId>com.wonderingwall</groupId> <artifactId>first-attempt</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>bootique-first-attempt</name> <properties> <main.class>com.wonderingwall.App</main.class> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>io.bootique.bom</groupId> <artifactId>bootique-bom</artifactId> <version>1.0.RC1</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.bootique</groupId> <artifactId>bootique</artifactId> </dependency> <dependency> <groupId>io.bootique.jersey</groupId> <artifactId>bootique-jersey</artifactId> </dependency> <dependency> <groupId>io.bootique.logback</groupId> <artifactId>bootique-logback</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-shade-plugin</artifactId> </plugin> </plugins> </build> </project> -
创建
App.Javazzw:boonique_fist_attempt zzw$ vi src/main/java/com/wonderingwall/App.java package com.wonderingwall; import com.google.inject.Binder; import com.google.inject.Module; import io.bootique.Bootique; import io.bootique.jersey.JerseyModule; /** * Hello world! */ public class App implements Module { public static void main(String[] args) { Bootique.app(args) .autoLoadModules() .module(App.class) .exec() .exit(); } @Override public void configure(Binder binder) { JerseyModule.extend(binder).addResource(HelloApi.class); } } -
创建RestApi接口类
HelloApi.java。这里符合Java JAX-RS API标准zzw:boonique_fist_attempt zzw$ vi src/main/java/com/wonderingwall/HelloApi.java package com.wonderingwall; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/") public class HelloApi { @GET @Produces(MediaType.APPLICATION_JSON) public String get() { return "{\"message\":\"Hello, Bootique!!\"}"; } } -
看下未编译前的目录结构
zzw:boonique_fist_attempt zzw$ tree . . ├── pom.xml └── src └── main └── java └── com └── wonderingwall ├── App.java └── HelloApi.java 5 directories, 4 files -
编译项目
zzw:boonique_fist_attempt zzw$ mvn clean package [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building bootique-first-attempt 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ first-attempt --- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ first-attempt --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/src/main/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ first-attempt --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/target/classes [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ first-attempt --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ first-attempt --- [INFO] No sources to compile [INFO] [INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ first-attempt --- [INFO] No tests to run. [INFO] [INFO] --- maven-jar-plugin:3.1.0:jar (default-jar) @ first-attempt --- [INFO] Building jar: /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/target/first-attempt-0.0.1-SNAPSHOT.jar [INFO] [INFO] --- maven-shade-plugin:3.2.1:shade (default) @ first-attempt --- [INFO] Including io.bootique:bootique:jar:1.0.RC1 in the shaded jar. [INFO] Including com.google.inject:guice:jar:4.2.0 in the shaded jar. [INFO] Including javax.inject:javax.inject:jar:1 in the shaded jar. [INFO] Including aopalliance:aopalliance:jar:1.0 in the shaded jar. [INFO] Including com.google.guava:guava:jar:23.6-android in the shaded jar. [INFO] Including org.checkerframework:checker-compat-qual:jar:2.0.0 in the shaded jar. [INFO] Including com.fasterxml.jackson.core:jackson-databind:jar:2.9.5 in the shaded jar. [INFO] Including com.fasterxml.jackson.core:jackson-annotations:jar:2.9.5 in the shaded jar. [INFO] Including com.fasterxml.jackson.core:jackson-core:jar:2.9.5 in the shaded jar. [INFO] Including com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.9.5 in the shaded jar. [INFO] Including org.yaml:snakeyaml:jar:1.18 in the shaded jar. [INFO] Including net.sf.jopt-simple:jopt-simple:jar:5.0.3 in the shaded jar. [INFO] Including io.bootique.jersey:bootique-jersey:jar:1.0.RC1 in the shaded jar. [INFO] Including io.bootique.jetty:bootique-jetty:jar:1.0.RC1 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-server:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including javax.servlet:javax.servlet-api:jar:3.1.0 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-http:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-util:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-io:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-servlet:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including org.eclipse.jetty:jetty-security:jar:9.4.12.v20180830 in the shaded jar. [INFO] Including org.slf4j:slf4j-api:jar:1.7.25 in the shaded jar. [INFO] Including javax.xml.bind:jaxb-api:jar:2.3.0 in the shaded jar. [INFO] Including javax.activation:activation:jar:1.1.1 in the shaded jar. [INFO] Including org.glassfish.jersey.containers:jersey-container-servlet:jar:2.27 in the shaded jar. [INFO] Including org.glassfish.jersey.containers:jersey-container-servlet-core:jar:2.27 in the shaded jar. [INFO] Including org.glassfish.jersey.core:jersey-server:jar:2.27 in the shaded jar. [INFO] Including org.glassfish.jersey.core:jersey-client:jar:2.27 in the shaded jar. [INFO] Including org.glassfish.jersey.media:jersey-media-jaxb:jar:2.27 in the shaded jar. [INFO] Including javax.validation:validation-api:jar:1.1.0.Final in the shaded jar. [INFO] Including javax.ws.rs:javax.ws.rs-api:jar:2.1 in the shaded jar. [INFO] Including org.glassfish.jersey.core:jersey-common:jar:2.27 in the shaded jar. [INFO] Including javax.annotation:javax.annotation-api:jar:1.2 in the shaded jar. [INFO] Including org.glassfish.hk2:osgi-resource-locator:jar:1.0.1 in the shaded jar. [INFO] Including org.glassfish.jersey.inject:jersey-hk2:jar:2.27 in the shaded jar. [INFO] Including org.glassfish.hk2:hk2-locator:jar:2.5.0-b42 in the shaded jar. [INFO] Including org.glassfish.hk2:hk2-api:jar:2.5.0-b42 in the shaded jar. [INFO] Including org.glassfish.hk2:hk2-utils:jar:2.5.0-b42 in the shaded jar. [INFO] Including org.javassist:javassist:jar:3.22.0-CR2 in the shaded jar. [INFO] Including io.bootique.logback:bootique-logback:jar:1.0.RC1 in the shaded jar. [INFO] Including ch.qos.logback:logback-classic:jar:1.1.9 in the shaded jar. [INFO] Including ch.qos.logback:logback-core:jar:1.1.9 in the shaded jar. [INFO] Including org.slf4j:jul-to-slf4j:jar:1.7.25 in the shaded jar. [WARNING] Discovered module-info.class. Shading will break its strong encapsulation. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/target/first-attempt-0.0.1-SNAPSHOT.jar with /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/target/first-attempt-0.0.1-SNAPSHOT-shaded.jar [INFO] Dependency-reduced POM written at: /Users/zzw/Develop/workspace/github/WonderingWall/challenge/boonique_fist_attempt/dependency-reduced-pom.xml [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 7.637 s [INFO] Finished at: 2020-03-28T21:43:04+08:00 [INFO] Final Memory: 39M/292M [INFO] ------------------------------------------------------------------------ -
编译后目录结构如下
zzw:boonique_fist_attempt zzw$ tree . . ├── dependency-reduced-pom.xml ├── pom.xml ├── src │ └── main │ └── java │ └── com │ └── wonderingwall │ ├── App.java │ └── HelloApi.java └── target ├── classes │ └── com │ └── wonderingwall │ ├── App.class │ └── HelloApi.class ├── first-attempt-0.0.1-SNAPSHOT.jar ├── generated-sources │ └── annotations ├── maven-archiver │ └── pom.properties ├── maven-status │ └── maven-compiler-plugin │ └── compile │ └── default-compile │ ├── createdFiles.lst │ └── inputFiles.lst └── original-first-attempt-0.0.1-SNAPSHOT.jar -
直接运行jar可以得到一份类似命令行帮助文档。
zzw:boonique_fist_attempt zzw$ java -jar target/first-attempt-0.0.1-SNAPSHOT.jar NAME first-attempt-0.0.1-SNAPSHOT.jar OPTIONS -c yaml_location, --config=yaml_location Specifies YAML config location, which can be a file path or a URL. -h, --help Prints this message. -H, --help-config Prints information about application modules and their configuration options. -s, --server Starts Jetty server. -
上面帮助我们可以看到,我们只要加入
--server就可以运行我们的程序了。zzw:boonique_fist_attempt zzw$ java -jar target/first-attempt-0.0.1-SNAPSHOT.jar -s INFO [2020-03-28 13:53:25,051] main o.e.jetty.util.log: Logging initialized @1628ms to org.eclipse.jetty.util.log.Slf4jLog INFO [2020-03-28 13:53:25,181] main i.b.j.s.ServerFactory: Adding listener io.bootique.jetty.servlet.DefaultServletEnvironment INFO [2020-03-28 13:53:25,191] main i.b.j.s.ServletFactory: Adding servlet 'jersey' mapped to /* INFO [2020-03-28 13:53:25,249] main i.b.j.s.ServerLifecycleLogger: Starting jetty... INFO [2020-03-28 13:53:25,253] main o.e.j.server.Server: jetty-9.4.z-SNAPSHOT; built: 2018-08-30T13:59:14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 1.8.0_161-b12 INFO [2020-03-28 13:53:25,314] main o.e.j.server.session: DefaultSessionIdManager workerName=node0 INFO [2020-03-28 13:53:25,314] main o.e.j.server.session: No SessionScavenger set, using defaults INFO [2020-03-28 13:53:25,320] main o.e.j.server.session: node0 Scavenging every 660000ms WARN [2020-03-28 13:53:25,964] main o.g.j.i.i.Providers: A provider com.wonderingwall.HelloApi registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider com.wonderingwall.HelloApi will be ignored. INFO [2020-03-28 13:53:26,177] main o.e.j.s.h.ContextHandler: Started o.e.j.s.ServletContextHandler@704b2127{/,null,AVAILABLE} INFO [2020-03-28 13:53:26,250] main o.e.j.s.AbstractConnector: Started ServerConnector@2f24886a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080} INFO [2020-03-28 13:53:26,251] main o.e.j.server.Server: Started @2834ms INFO [2020-03-28 13:53:26,399] main i.b.j.s.ServerLifecycleLogger: Started Jetty in 1002 ms. Base URL: http://127.0.0.1:8080/浏览器中键入
http://localhost:8080就可以获得我们所需的结果了。

-
路径配置则是通过yaml文件配置。你可以查看帮助文件使用
-H参数。我这里添加了config.ymlzzw:boonique_fist_attempt zzw$ cat config.yml jetty: context: /hello connectors: - port: 8088 -
运行结果如下
zzw:boonique_fist_attempt zzw$ java -jar target/first-attempt-0.0.1-SNAPSHOT.jar -s --config=config.yml INFO [2020-03-28 13:54:54,640] main o.e.jetty.util.log: Logging initialized @1775ms to org.eclipse.jetty.util.log.Slf4jLog INFO [2020-03-28 13:54:54,725] main i.b.j.s.ServerFactory: Adding listener io.bootique.jetty.servlet.DefaultServletEnvironment INFO [2020-03-28 13:54:54,737] main i.b.j.s.ServletFactory: Adding servlet 'jersey' mapped to /* INFO [2020-03-28 13:54:54,794] main i.b.j.s.ServerLifecycleLogger: Starting jetty... INFO [2020-03-28 13:54:54,798] main o.e.j.server.Server: jetty-9.4.z-SNAPSHOT; built: 2018-08-30T13:59:14.071Z; git: 27208684755d94a92186989f695db2d7b21ebc51; jvm 1.8.0_161-b12 INFO [2020-03-28 13:54:54,844] main o.e.j.server.session: DefaultSessionIdManager workerName=node0 INFO [2020-03-28 13:54:54,844] main o.e.j.server.session: No SessionScavenger set, using defaults INFO [2020-03-28 13:54:54,848] main o.e.j.server.session: node0 Scavenging every 600000ms WARN [2020-03-28 13:54:55,409] main o.g.j.i.i.Providers: A provider com.wonderingwall.HelloApi registered in SERVER runtime does not implement any provider interfaces applicable in the SERVER runtime. Due to constraint configuration problems the provider com.wonderingwall.HelloApi will be ignored. INFO [2020-03-28 13:54:55,618] main o.e.j.s.h.ContextHandler: Started o.e.j.s.ServletContextHandler@73386d72{/hello,null,AVAILABLE} INFO [2020-03-28 13:54:55,700] main o.e.j.s.AbstractConnector: Started ServerConnector@226f556a{HTTP/1.1,[http/1.1]}{0.0.0.0:8088} INFO [2020-03-28 13:54:55,700] main o.e.j.server.Server: Started @2846ms INFO [2020-03-28 13:54:55,709] main i.b.j.s.ServerLifecycleLogger: Started Jetty in 907 ms. Base URL: http://127.0.0.1:8088/hello浏览器中键入
http://localhost:8088/hello

总结
总体的开发流程和SpringBoot差不多,运行的速度的确显而易见,毕竟Guice是Google开源的一个依赖注入类库,相比于Spring IoC来说更小更快。Bootique文档不多,但是入门够用,要一定的开发基础才能深入。关注度也不够高。不过的确很适合现在的微服务架构轻量级的开发,快速而高效。我这里直接Vim编写了,没有用到IDE,稍微有所了解还好,否则没有提示开发难度还是会上升,幸亏只是基于Maven管理。