"Spring Boot real" two: first application development

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/yuan1164345228/article/details/94762943

This chapter uses the Spring Boot achieve a simple example, includes two knowledge points:

  • Use the start-dependent Spring Boot
  • Automatically using the Boot Spring Spring configuration

2.1 use Spring Boot

The following will create a simple reading list uses Spring Boot, the user can input information want to read the book to see the list, delete the already read the book.

First, Spring Boot Initialization projects, from a technical point of view, we use Spring MVC to handle Web requests, with Thymeleaf to define the Web view with Spring Data JPA to the reading list persisted to the database, first with embedded here the H2 database. We use Initializr the Web interface to initialize, add the Web, Thymeleaf in place and add a dependency of JPA . Also add H2 , in order to use the embedded database when developing applications.

After initialization file structure:

2.1.1 ReadListApplication.java

首先看ReadListApplication.java,ReadListApplication在Spring Boot应用程序里有两个作用:配置和启动引导。首先, 这是主要的Spring配置类。虽然Spring Boot的自动配置免除了很多Spring配置,但你还需要进行 少量配置来启用自动配置。@SpringBootApplication开启了Spring的组件扫描和Spring Boot的自动配置功能。实际 上,@SpringBootApplication将三个有用的注解组合在了一起。

  • Spring@Configuration:标明该类使用Spring基于Java的配置。
  • Spring@ComponentScan:启用组件扫描,这样你写的Web控制器类和其他组件才能被 自动发现并注册为Spring应用程序上下文里的Bean。本章稍后会写一个简单的Spring MVC 控制器,使用@Controller进行注解,这样组件扫描才能找到它。
  • Spring Boot @EnableAutoConfiguration :这个注解也可以称为 @Abracadabra,就是这一行配置开启了Spring Boot自动配置的魔力,让你不用再写成篇的配置了。

如前所述,ReadListApplication还有一个作用是启动引导,运行Spring Boot应用程序有两种方式:一是通过传统的WAR包形式;二是通过可执行jar包的方式。这里向SpringApplication.run()传递了一个ReadingListApplication类的引用,还有命令行参数,通过这些东西启动应用程序。

package com.yuan.readlist;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication    //开启组件扫描和自动配置
public class ReadlistApplication {

	public static void main(String[] args) {
		SpringApplication.run(ReadlistApplication.class, args); //负责启动引导应用程序
	}
}

2.1.2 ReadlistApplicationTests.java

ReadingListApplicationTests不仅提供了一个用于测试Spring Boot项目的框架,它还是一个例子,告诉你如何为Spring Boot应用程序编写测试。

contextLoads()这个空方法足以证明应用程序上下文的加载没有问题,如果ReadingListApplication里定义的配置是好的,就能通过测试。如果有问题,测试就会失败。

当然,现在这只是一个新的应用程序,你还会添加自己的测试。但contextLoads()方法是个良好的开端,此刻可以验证应用程序提供的各种功能。第4章会更详细地讨论如何测试Spring Boot应用程序。

package com.yuan.readlist;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ReadlistApplicationTests {

	@Test
	public void contextLoads() {
	}
}

2.1.3 application.properties

Initializr为你生成的application.properties文件是一个空文件,该文件可以用来调整Spring Boot的自动配置。

要注意的是,你完全不用告诉Spring Boot为你加载application.properties,只要它存在就会被加载,Spring和应用程序代码都能获取其中的属性,当然如果它不存在也完全没有问题,Spring Boot会使用其默认配置。

2.1.4 运行项目

构建一个Spring Boot应用程序和构建其他Java应用程序的过程类似,可以选择GradleMaven作为构建工具。描述构建说明文件的方法和描述非Spring Boot应用程序的方法也相似。Spring BootGradleMaven提供了构建插件,以便辅助构建Spring Boot项目。

将项目导入到MyEclipse中,执行ReadlistApplication的main方法,即可运行项目,然后浏览器访问127.0.0.1:8080,由于还没有写控制器类,会打开一个404的错误页面。

2.2 使用起步依赖

指定基于功能的依赖

通过使用Spring Boot的起步依赖,可以使我们不用指定具体的版本号,甚至不需要指定具体使用的依赖。比如我们前面在引入依赖时,我们只是在Initializr添加了WebThymeleaf、JPA和H2,而通过传递依赖,它们声明的依赖也会被传递依赖进来,添加这四个依赖就等价于将相关的库都添加了进来。在《Spring Boot实战》附录B罗列出了全部起步依赖,并简要描述了一下它们向项目构建引入了什么。

覆盖起步依赖引入的传递依赖

起步依赖和你项目里的其他依赖没什么区别。也就是说,你可以通过构建工具中的功能,选择性地覆盖它们引入的传递依赖的版本号,排除传递依赖,当然还可以为那些Spring Boot起步依赖没有涵盖的库指定依赖。在Maven里,可以用元素来排除传递依赖。

Maven总是会用最近的依赖,也就是说,如果你在项目里想要覆盖Spring Boot引入的传递依赖,可以直接在在项目的构建说明文件里增加的这个依赖。

(关于起步依赖更多详细内容,参考《Spring Boot实战》2.2节使用起步依赖。)

2.3 使用自动配置

简每当应用程序启动的时候,Spring Boot检测ClassPath中包含的包,并对包含的包做一个基本的配置。比如Spring Security是不是在Classpath里?如果是,则进行一个非常基本的Web安全设置。

每当应用程序启动的时候,Spring Boot的自动配置都要做将近200个这样的决定,涵盖安全、 集成、持久化、Web开发等诸多方面。所有这些自动配置就是为了尽量不让你自己写配置,从而更多的专注于程序的功能。

下面我们继续ReadList的功能实现:

  • 定义领域模型

读者阅读列表上的书是本例的核心领域概念,我们定义一个实体类Book来表示这个概念。

@Entity注解表明它是一个JPA实体,id属性加了@Id@GeneratedValue注解,说明这个字段是实体的唯一标识,并且这个字段的值是自动生成的。

package com.yuan.readlist;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Book {
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	private String reader;
	private String isbn;
	private String title;
	private String author;
	private String description;
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getReader() {
		return reader;
	}
	public void setReader(String reader) {
		this.reader = reader;
	}
	public String getIsbn() {
		return isbn;
	}
	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
}
  • 定义仓库接口

用于把Book对象持久化到数据库的仓库了。因为用了Spring Data JPA,所以我们要做的就是简单地定义一个接口,扩展一下Spring Data JPAJpaRepository接口:

package com.yuan.readlist;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ReadingListRepository extends JpaRepository<Book, Long> {
	List<Book> findByReader(String reader);
}

通过扩展JpaRepositoryReadingListRepository直接继承了18个执行常用持久化操作的方法。JpaRepository是个泛型接口,有两个参数:仓库操作的领域对象类型,及其ID属性的类型。此外,我还增加了一个findByReader()方法,可以根据读者的用户名来查找阅读列表。 如果你好奇谁来实现这个ReadingListRepository及其继承的18个方法,请不用担心,Spring Data提供了很神奇的魔法,只需定义仓库接口,在应用程序启动后,该接口在运行时会自动实现。

  • 创建控制器

我们创建Spring MVC控制器来处理HTTP请求。ReadingListController使用了@Controller注解,这样组件扫描会自动将其注册为 Spring应用程序上下文里的一个Bean。它还用了@RequestMapping注解,将其中所有的处理器 方法都映射到了“/”这个URL路径上。

package com.yuan.readlist;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.List;
@Controller
@RequestMapping("/")
public class ReadingListController {
	private ReadingListRepository readingListRepository;
	@Autowired
	public ReadingListController(ReadingListRepository readingListRepository) {
		this.readingListRepository = readingListRepository;
	}
	@RequestMapping(value = "/{reader}", method = RequestMethod.GET)
	public String readersBooks(@PathVariable("reader") String reader,
			Model model) {
		List<Book> readingList = readingListRepository.findByReader(reader);
		if (readingList != null) {
			model.addAttribute("books", readingList);
		}
		return "readingList";
	}
	@RequestMapping(value = "/{reader}", method = RequestMethod.POST)
	public String addToReadingList(@PathVariable("reader") String reader,
			Book book) {
		book.setReader(reader);
		readingListRepository.save(book);
		return "redirect:/{reader}";
	}
}

该控制器有两个方法。

readersBooks():处理/{reader}上的HTTP GET请求,根据路径里指定的读者,从(通过控制器的构造器注入的)仓库获取Book列表。随后将这个列表塞入模型,用的键是books,最后返回readingList作为呈现模型的视图逻辑名称。

addToReadingList():处理/{reader}上的HTTP POST请求,将请求正文里的数据绑定到一个Book对象上。该方法把Book对象的reader属性设置为读者的姓名,随后通过仓库的save()方法保存修改后的Book对象,最后重定向到/{reader}(控制器中的另一个方法会处理该请求)。

  • 创建WEB界面

readersBooks()方法最后返回readingList作为逻辑视图名,为此必须创建该视图。因为在项目开始之初就决定要用Thymeleaf来定义应用程序的视图,所以接下来就在src/main/resources/templates里创建一个名为readingList.html的文件:

<html>
<head>
<title>Reading List</title>
<link rel="stylesheet" th:href="@{/style.css}"></link>
</head>
<body
	<h2>Your Reading List</h2>
	<div th:unless="${#lists.isEmpty(books)}">
		<dl th:each="book : ${books}">
			<dt class="bookHeadline">
				<span th:text="${book.title}">Title</span> by <span
					th:text="${book.author}">Author</span> (ISBN: <span
					th:text="${book.isbn}">ISBN</span>)
			</dt>
			<dd class="bookDescription">
				<span th:if="${book.description}" th:text="${book.description}">Description</span>
				<span th:if="${book.description eq null}"> No description
					available</span>
			</dd>
		</dl>
	</div>
	<div th:if="${#lists.isEmpty(books)}">
		<p>You have no books in your book list</p>
	</div>
	<hr />
	<h3>Add a book</h3>
	<form method="POST">
		<label for="title">Title:</label> <input type="text" name="title"
			size="50"></input><br /> <label for="author">Author:</label> <input
			type="text" name="author" size="50"></input><br /> <label for="isbn">ISBN:</label>
		<input type="text" name="isbn" size="15"></input><br /> <label
			for="description">Description:</label><br />
		<textarea name="description" cols="80" rows="5"> 
 </textarea>
		<br /> <input type="submit"></input>
	</form>
</body>
</html>

添加名为style.css的样式文件,该文件位于src/main/resources/static目录:

body { 
 background-color: #cccccc; 
 font-family: arial,helvetica,sans-serif; 
} 
.bookHeadline { 
 font-size: 12pt; 
 font-weight: bold; 
}
.bookDescription { 
 font-size: 10pt; 
} 
label { 
 font-weight: bold; 
}
  • 运行程序

到目前为止,我们就已经完成了一个完整的Spring WEB程序,可见我们并没有进行什么配置,所有的配置都是Spring Boot自动完成的。

下面我们来运行这个WEB程序,在MyEclipse中右键,Run as Java Application,然后浏览器访问127.0.0.1:8080/name即可打开网页,可提交查询表单。

关于Spring Boot自动配置更多内容,及其如何实现自动配置功能,参见《Spring Boot实战》2.3.3节内容。

2.4 总结

通过Spring Boot的起步依赖和自动配置,你可以更加快速、便捷地开发Spring应用程序。在下一章,我们将会看到如何覆盖Spring Boot自动配置,借此达成应用程序的一些特殊要求,还有如何运用类似的技术来配置自己的应用程序组件。

Guess you like

Origin blog.csdn.net/yuan1164345228/article/details/94762943