硬核干货——《中小企业 AI 实战指南》免费下载! 了解详情
写点什么

使用 Spring Boot 快速构建应用

  • 2014-01-20
  • 本文字数:3794 字

    阅读完需:约 12 分钟

随着 Spring 4 新版本的发布 Spring Boot 这个新的子项目得到了广泛的关注,因为不管是 Spring 4 官方发布的新闻稿还是针对首席架构师Adrian Colyer 的专访,都对这个子项目所带来的生产率提升赞誉有加。

Spring Boot 充分利用了 JavaConfig 的配置模式以及“约定优于配置”的理念,能够极大的简化基于 Spring MVC 的 Web 应用和 REST 服务开发。

Spring 4 倡导微服务的架构,针对这一理念,近来在微博上也有一些有价值的讨论,如这里这里。微服务架构倡导将功能拆分到离散的服务中,独立地进行部署,Spring Boot 能够很方便地将应用打包成独立可运行的 JAR 包,因此在开发模式上很契合这一理念。目前,Spring Boot 依然是 0.5.0 的里程碑版本,因此相关的文档尚不完善,本文将会以一个简单的样例来介绍基于这个项目的开发过程。

要 Spring Boot 进行功能开发,需要使用 Gradle 或者 Maven 作为构建工具。在本例中,我们会使用 Eclipse 和 Maven 插件进行开发。要使用 Spring Boot,首先创建一个 Maven 工程,并修改 Maven 主要的配置文件 pom.xml,如下所示:

复制代码
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>0.5.0.M7</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring3</artifactId>
</dependency>
</dependencies>
<properties>
<start-class>com.levin.Application</start-class>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestone</id>
<url>http://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-milestone</id>
<url>http://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>

在上面的配置中,需要将工程的 parent 设置为 spring-boot-starter-parent,并添加对 spring-boot-starter-web 的依赖,这样我们就无需设置各个依赖项及其版本信息了。并且在构建中要声明使用 spring-boot-maven-plugin 这个插件,它会对 Maven 打包形成的 JAR 进行二次修改,最终产生符合我们要求的内容结构。

在我们的应用中将要发布一个 REST 服务,显示一个基本的用户信息,首先定义一个简单的模型类:

复制代码
package com.levin;
public class Person {
private String name;
private String email;
public Person(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}

接下来,我们需要声明一个 Spring MVC 的 Controller,响应对实体的请求:

复制代码
@Controller
public class ShowPersonController {
@RequestMapping("/showPerson")
public @ResponseBody Person showPerson() {
return new Person("levinzhang","levinzhang1981@gmail.com");
}
}

这个类与我们在使用 Spring MVC 定义 Controller 时并无任何差别。接下来,我们需要声明一个主类启动这个应用程序:

复制代码
@ComponentScan
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

这个类的 main 方法中使用了 SpringApplication 帮助类,并以 Application 这个类作为配置来启动 Spring 的应用上下文。在这个类中使用了 ComponentScan 以及 EnableAutoConfiguration 注解,其中 ComponentScan 注解会告知 Spring 扫描指定的包来初始化 Spring Bean,这能够确保我们声明的 Bean 能够被发现。EnableAutoConfiguration 将会启动自动配置模式,在我们的配置中会将对 Tomcat 的依赖级联进来,因此在应用启动时将会自动启动一个嵌入式的 Tomcat,因为在样例中使用了 Spring MVC,所以也会自动注册所需的 DispatcherServlet,这都不需要类似 web.xml 这样的配置。

在 Eclipse 中要运行这个应用的话,可以直接以 Java Application 的形式来运行这个 main 函数,此时会启动应用,我们在浏览器中可以看到如下的运行效果,这就是我们想要的 REST 服务:

在开发调试完成之后,可以将应用打成 JAR 包的形式,在 Eclipse 中可以直接使用 Maven 插件的 package 命令,最终会形成一个可运行的 JAR 包。我们使用 java –jar 命令就可以运行这个 JAR 包了。所呈现出的效果与在调试期是一样的。现在看一下这个 JAR 包解压后的目录结构:

这个 JAR 包与传统 JAR 包的不同之处在于里面有一个名为 lib 的目录,在这个目录中包含了这个简单应用所依赖的其他 JAR 包,其中也包含内置的嵌入式 Tomcat,正是使用它,才能发布服务和访问 Web 资源。除了我们编写的源码所编译形成的 CLASS 以外,在 org 目录下还有许多 Spring 所提供的 CLASS,正是依赖这些 CLASS,才能够加载位于 lib 目录下 JAR 中的类。这样的加载机制与在 OSGi bundle 中声明 Bundle-Classpath 很类似,不过在 OSGi 中会由容器来负责加载指定路径下的类。这大致阐述了这样一个 JAR 包能够发布服务的原因。

如果我们想要使用 HTML、JSP 等 Web 资源的话,在 Controller 中直接返回对应的视图就可以了。

如果我们想要将这个 JAR 包转换成可以在 Servlet 容器中部署的 WAR 的话,就不能依赖于 Application 的 main 函数了,而是要以类似于 web.xml 文件配置的方式来启动 Spring 应用上下文,此时我们需要声明这样一个类:

复制代码
public class HelloWebXml extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}

这个类的作用与在 web.xml 中配置负责初始化 Spring 应用上下文的监听器作用类似,只不过在这里不需要编写额外的 XML 文件了。

如果要将最终的打包形式改为 WAR 的话,还需要对 pom.xml 文件进行修改,除了需要将 packaging 的值修改为 war 以外,还需要对依赖进行适当的配置(这一部分在 Spring Boot 的样例和文档中均未提及,提醒大家注意):

复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>

在这里需要移除对嵌入式 Tomcat 的依赖,这样打出的 WAR 包中,在 lib 目录下才不会包含 Tomcat 相关的 JAR 包,否则将会出现启动错误。另外,在移除对 Tomcat 的依赖后,为了保证编译正确,还需要添加对 servlet-api 的依赖,因此添加如下的配置:

复制代码
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>7.0.42</version>
<scope>provided</scope>
</dependency>

在这里将 scope 属性设置为 provided,这样在最终形成的 WAR 中不会包含这个 JAR 包,因为 Tomcat 或 Jetty 等服务器在运行时将会提供相关的 API 类。此时,执行 mvn package 命令就会得到一个 WAR 文件,我们可以直接将其放到 Tomcat 下运行(需要 7.0.42 版本以上)。

以上介绍了基于 Spring Boot 开发应用的过程,目前它的文档尚不完善,但是在 GitHub 上有不少的样例,包括与 Spring Data 集成访问数据库(关系型以及非关系型)、安全、WebSocket 等,读者感兴趣可以下载运行,需要注意的是有些样例中使用的是 0.5.0.M6 版本,这个版本有问题,运行时会出错,建议手动修改为 0.5.0.M7 或快照版本。

基于以上的介绍,希望读者能够对 Spring Boot 这个新项目有所了解。它简化了 JAR 包管理和相关基础设施环境的配置,能够帮助我们快速开发 Web 应用或构建 REST 服务,希望它能够尽快完善成熟,更多地用于实践,提升开发效率。

参考资料

http://projects.spring.io/spring-boot/

http://projects.spring.io/spring-boot/docs/README.html

http://spring.io/guides/gs/spring-boot/

http://spring.io/guides/gs/actuator-service/

http://spring.io/guides/gs/convert-jar-to-war/

2014-01-20 23:2340182

评论

发布
暂无评论
发现更多内容

从源码中来,到业务中去,React性能优化终极指南

有道技术团队

大前端 React 有道精品课

BI系统里的数据赋能与业务决策

薄荷点点

数据产品经理 决策 BI 数据驱动 风险识别

VSCode 无鼠标操作快捷键对比Atom

追风的少年

另一种总结的方式

Nydia

学习

并发王者课-青铜6:借花献佛-如何格式化Java内存工具JOL输出

MetaThoughts

Java 多线程 并发 并发王者课

Qemu KVM Guest增强简述

焱融科技

云计算 虚拟机 高性能 存储 qemu

网格策略交易软件,量化马丁倍投交易机器人

2021年爆火的低代码开发技术,对企业而言有什么好处?

优秀

低代码

索信达控股:金融机构如何打造最适合自己的个性化推荐系统?

索信达控股

大数据 金融科技 金融 个性化推荐 营销数字化

OCR性能优化:从神经网络到橡皮泥

华为云开发者联盟

神经网络 机器学习 OCR 橡皮泥 CNN网络

哈工大与华为终端有限公司签署首个HarmonyOS高校协同育人合作协议

科技汇

【Flutter 专题】124 日常问题小结 (三) 自定义 Dialog 二三事

阿策小和尚

5月日更 Flutter 小菜 0 基础学习 Flutter Android 小菜鸟

☕️【Java 技术之旅】从底层分析LockSupport原理机制

码界西柚

Java JVM lock锁 5月日更 LockSupport

实测Tengine开源的Dubbo功能

捉虫大师

dubbo 网关 tengine

NUCLEO-L432KC实现UART1、UART2双串口数据通信(STM32L432KC)

不脱发的程序猿

嵌入式 stm32 单片机 NUCLEO-L432KC 串口通信

2021百度之星报名开启 特设“小星星”奖项鼓励少年AI人才

百度大脑

AI 百度之星 少年

为什么你的Docker容器刚启动就停了?

运维研习社

Docker Linux 5月日更

并发王者课-青铜5:一探究竟-如何从synchronized理解Java对象头中的锁

MetaThoughts

Java 多线程 并发 并发王者课

MySQL 数据库救火:磁盘爆满了,怎么办?

华为云开发者联盟

数据库 磁盘 MySQL 数据库 日志文件 磁盘爆满

GitHub开源14.5万行阿波罗11号源代码

不脱发的程序猿

GitHub 开源 阿波罗11号

要想成为牛人,推荐学习哪种编程语言?

实力程序员

教你用User Story设计BI驾驶舱

薄荷点点

数据产品经理 用户故事地图 产品需求

阿里云联合中国信通院发布《云计算开放应用架构》标准,加速云原生应用规模化落地进程

阿里巴巴云原生

容器 开发者 运维 云原生 k8s

合作伙伴眼中的HarmonyOS 专访方太智能厨电专家俞贵涛

科技汇

谋而后动:解读数仓计划生成中行数估算和路径生成的奥秘

华为云开发者联盟

计划 数仓 GaussDB(DWS) 查询语句 估算

聊聊微服务治理的落地问题 | Geek大咖说第二期

百度Geek说

微服务 自动化

集成学习中的随机森林

华为云开发者联盟

机器学习 决策树 随机森林 集成学习 Bagging

集群镜像:实现高效的分布式应用交付

阿里巴巴云原生

数据库 容器 开发者 云原生 存储

最佳入门系列 | 何为服务网关?

架构精进之路

微服务 5月日更

Django 之视图篇

若尘

django 视图 Python编程 5月日更

《复仇者联盟》AI换脸平台

不脱发的程序猿

人工智能 开源 AI 复仇者联盟

使用Spring Boot快速构建应用_Java_张卫滨_InfoQ精选文章