栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot入门

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot入门

SpringBoot入门
  • 一、SpringBoot简介
  • 二、Java EE应用与Spring
  • 三、SpringBoot优势
  • 四、SpringBoot应用打包类型
  • 五、pom.xml文件
  • 六、编写控制器
  • 七、定义视图页面
  • 八、运行应用
  • 九、创建可执行的JAR包
  • 十、执行JAR包启动SpringBoot应用
  • 十一、Maven生命周期
  • 十二、开发业务组件
  • 十三、开发DAO组件
  • 十三、编写单元测试
    • 1.测试RESTful接口

创建第一个SpringBoot应用:

  • IDEA 创建第一个Springboot程序
一、SpringBoot简介

Springboot是Java企业开发里最流行的框架,它为各种第三方框架的快速整合提供了自动配置,一旦用上了SpringBoot,开发者只需专注于应用中业务逻辑功能的实现。

二、Java EE应用与Spring

Spring是Java领域中应用最广的框架,从本质上说:

  • Spring只是一个组件容器,负责创建并管理容器中的组件(称为Bean),并管理组件之间的依赖关系。
  • 由于Spring将容器功能做到了极致,Java EE应用所涉及的以下各种组件,都处于Spring容器的管理之下:
  • 前端控制器组件
  • 安全组件
  • 业务逻辑组件
  • 消息组件
  • DAO组件(Spring也称其为Repository)
  • 连接数据库的基础组件(如DataSource、ConnectionFactory、SessionFactory等)

对于其他各种功能型的框架,它们都需要一个容器来承载其运行,而Spring正是这个不可替代的容器。

关于Java领域中的功能型框架,各方面的功能都存在不少框架可供选择:

  • 前端:Spring WebFlux、Spring MVC、Struts2
  • 安全领域:Spring Security、Shiro等
  • 消息组件:ActiveMQ、RabbitMQ、Kafka等
  • 缓存:JCache、EhCache、Hazelcast、Redis等
  • 持久层框架:JPA、MyBatis、jOOQ、R2DBC
  • 分布式:ZooKeeper、Dubbo等
  • NoSQL存储:Redis、MongoDB、Neo4j、Cassandra、Geodo等
  • 搜索引擎:Lucene、Solr、Elasticsearch等
  • 数据库存储:MySQL、PostgreSQL、Oracle等
  • Web服务器:Tomcat、Jetty、Undertow等

作为容器的Spring,是无可替代的,上面列出的这些框架,它们都需要与Spring进行整合,这就是Spring的魅力

传统Spring使用XML配置或注解来管理这些组件,因此搭建一个Java EE应用往往需要进行大量的配置和注解。这些配置工作都属于项目的基础搭建,与业务功能无关,这些工作对于初、中级开发者往往难度不小,很容易出错,在这种背景下,Spring推出了SpringBoot。

三、SpringBoot优势

Spring框架唯一的缺点是配置过多,搭建项目时需要进行大量的配置,而SpringBoot的出现,就是为了解决这个问题。

SpringBoot为绝大部分第三方框架的快速整合提供了自动配置,SpringBoot使用约定优先于配置的理念,针对企业应用开发各种场景提供了对应的Starter,开发者只要将该Starter添加到项目的类加载路径中,该Starter即可完成第三方框架的整合。

总体来说:SpringBoot具有以下特性:

  • 内嵌Tomcat、Jetty或Undertow服务器,因此SpringBoot应用无需被部署到其他服务器中。
  • SpringBoot应用可被做成独立的Java应用程序。
  • 尽可能地自动配置Spring及第三方框架。
  • 完全没有代码生成,也不需要XML配置
  • 提供产品级监控功能,如运行状况检查和外部化配置等

SpringBoot主要功能就是:

  • 为Spring及第三方框架的快速启动提供自动配置
  • 当Spring及第三方框架整合起来之后,SpringBoot的责任也就完成了
  • 在实际开发中发挥功能的依然是前面列出的那些框架和技术
四、SpringBoot应用打包类型

由于SpringBoot内嵌了Tomcat、Jetty或Undertow服务器,因此SpringBoot应用通常不需要被部署到Web服务器中,选择打包成JAR即可。

只有在极个别的情况下,不想使用SpringBoot内嵌服务器,才会考虑将它打包成WAR包(Web应用包),部署到独立的Web服务器中

五、pom.xml文件


    4.0.0

	
    com.bigdata.boot
    boot-helloworld
    1.0-SNAPSHOT

   
    
        8
        8
    

    
        org.springframework.boot
        spring-boot-starter-parent
        2.4.2
         
    

    
    	
        
            org.springframework.boot
            spring-boot-starter-web
        

 		
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

    

    
        
            
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.4.3
                
                    
                                                    org.springframework.boot
                            spring-boot-configuration-processor
                        
                    
                
            
        
    


六、编写控制器

SpringBoot的功能只是为整合提供自动配置,因此SpringBoot应用的控制器依然是Spring MVC、Spring WebFlux或Struts 2的控制器,具体定义哪种控制器取决于项目技术栈的前端框架,本例采用Spring MVC作为前端框架,因此这里定义一个Spring MVC的前端控制器类。

@Controller
public class BookController
{
	@GetMapping("/")
	public String index(Model model)
	{
	model.addAttribute("tip","欢迎访问第一个SpringBoot应用");
	return "hello";
	}


	@GetMapping("/rest")
	@ResponseBody
	public ResponseEntity restIndex()
	{
		return new ResponseEntity<>("欢迎访问第一个springboot应用",null,HttpStatus.OK);
	}
}

上面的BookController就是一个再普通不过的Spring MVC的控制器,@Controller、@GetMapping、@ResponseBody注解都是最基本的SpringMVC注解。

  • @Controller:用于修饰类,指定该类的实例作为控制器组件
  • @GetMapping:用于修饰方法,指定该方法所能处理的Get请求的地址
  • @ResponseBody:用于修饰方法,指定该方法生成Restful响应

上面的控制器类中定义了两个处理方法,其中第一个index()方法返回的"hello"字符串只是一个逻辑视图名,因此它还需要物理视图资源。

SpringBoot推荐使用Thymeleaf作为视图模版技术,同时可以使用BootStrap UI库美化界面。

使用前后端分离架构的应用,SpringBoot应用根本不需要生成视图响应,自然也就不需要任何视图模版技术了,在前后端分离架构的应用中,SpringBoot只需要对外提供Restful响应,前端应用则通过Restful接口与后端通信,前端应用负责生成界面,与用户交互。

七、定义视图页面

为BookController的第一个处理方法返回的"hello"逻辑视图名定义Thymeleaf视图页面hello.html

SpringBoot默认要求将Thymeleaf视图页面放在resourcetemplates目录下,因此需要将hello.html的视图放在该目录下。由于该页面是为hello逻辑视图名提供视图,因此该页面的文件名为"hello.html".

Thymeleaf视图页面的语法核心设计就是:以“th:”开头的属性来处理表达式的值,比如th:text属性的作用就是用目标HTML元素来显示表达式的值。

八、运行应用
package com.bigdata.boot;

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


@SpringBootApplication
public class MainApplication{
    public static void main(String[] args) {
    //创建Spring容器,运行SpringBoot应用
        SpringApplication.run(MainApplication.class,args);
    }
}

调用SpringApplication类的run()方法来创建Spring容器,运行SpringBoot应用。

SpringBoot是基于Spring框架的,而Spring框架最重要的核心就是Spring容器,对于Spring来说,万物都是Bean,而容器就是所有Bean所在的天地,负责管理所有Bean的生死。一个Spring容器就是天地万物,因此所有Spring框架的应用的第一步都是创建Spring容器。

SpringApplication类中run()方法的返回值就是ConfigurableApplicationContext,这就是Spring容器,可见run()方法将会创建并返回Spring容器

有了Spring容器之后,容器中的Bean来自任意用@Configuration注解修饰的Java类(Java配置类,相当于传统的XML配置文件),Spring容器会加载该配置类并创建该配置类中的所有Bean,并且会扫描该配置类相同包或其子包下的所有Bean。

run()方法的第一个参数是MainApplication类,该类应该是带@Configuration注解修饰的配置类。查看@SpringBootConfiguration源码,发现@SpringBootConfiguration就是@Configuration源码。由此可见,@SpringBootApplication注解相当于3个注解的组合版。

  • @Configuration:该注解修饰的类将作为Java配置类
  • @EnableAutoConfiguration:启用自动配置
  • @ComponentScan:指定零配置时扫描哪些包及其子包下的Bean

可见SpringBootConfiguration注解只是一个快捷方式,同时启用了3个注解,从而完成了3个功能:

  • 将被修饰的类变成Java配置类
  • 启用自动配置
  • 定义了Spring容器扫描Bean类的包及其子包

所谓的自动配置,只是SpringBoot提供了预配置。由于SpringBoot提供的预配置,因此开发者无须过多配置即可把项目搭建起来。被@SpringBootApplication修饰的类位于org.crazyit.firstboot包下,因此Spring容器会自动扫描并处理该包及其子包下的所有配置类(@Configuration注解修饰的类)和组件类(@Component、@Controller、@Service、@Repository等注解修饰的类)。

  • @Configuration、@Controller、@Service、@Repository等注解的本质都是@Component,Spring容器会扫描@Component修饰的类,将它变成容器中的Bean。

由于前面定义的控制器类BookController位于org.crazyit.firstboot.controller包下,且使用了@Controller修饰,因此Spring容器就能将它加载成容器中的Bean.

九、创建可执行的JAR包

由于SpringBoot应用内嵌了Web服务器(Tomcat、Jetty),所以无须将SpringBoot应用部署到其他Web服务器中,SpringBoot应用完全可以独立运行。

在发布SpringBoot应用时,只需要将该应用打包成一个可执行的JAR包,以后就可以使用该JAR包来运行SpringBoot应用了。

为了将SpringBoot应用打包成JAR包,需要保证在pom.xml文件中添加了Spring Boot Maven插件,也就是其中包含如下配置:


        
            
                org.springframework.boot
                spring-boot-maven-plugin
                2.4.3
                
                    
                                                    org.springframework.boot
                            spring-boot-configuration-processor
                        
                    
                
            
        
    

只要执行如下两条命令即可生成可执行的JAR包:

mvn clean
mvn package
  • mvn clean:用于清除所有在构建过程中生成的文件。
  • mvn package:指定执行到Maven生命周期的package阶段,用于生成可执行的JAR包
十、执行JAR包启动SpringBoot应用
java -jar firstboot-0.0.1-SNAPSHOT.jar
十一、Maven生命周期

mvn package命令会从默认生命周期的第一阶段一直执行到package阶段,Maven的默认生命周期包含compile(编译项目)->test(单元测试)->package(项目打包)->install(安装到本地仓库)->deploy(部署到远程)这几个核心阶段

十二、开发业务组件

前面控制器的处理方法直接返回了字符串作为响应,这在实际项目中肯定是不行的,实际项目中的控制器要调用业务组件来处理用户响应,因此需要开发一个业务组件来处理用户请求。

业务组件要实现添加图书、删除图书、列出全部图书这三个功能。下面是本例业务组件的接口代码。

serviceBookService.java

public interface BookService
{
	List getAllBooks();
	Integer addBook(Book book);
	void deleteBook(Integer id);
}

该Service组件的实现类则调用DAO组件的方法来实现上述方法。下面是BookService组件的实现类代码。
serviceimplBookServiceImpl.java

@Service
@Transactional(propagation=Propagation.REQUIRED,timeout=5)
public class BookServiceImp1 implements BookService
{
	//依赖注入容器中的BookDao组件
	@Autowired
	private BookDao bookDao;

	@Override
	public List getAllBooks()
	{
		return (List) bookDao.findAll();
	}

	@Override
	public Integer addBook(Book book)
	{
		book.save(book);
		return book.getId();
	}
	
	@Override
	public void deleteBook(Integer id)
	{
		bookDao.deleteById(id);
	}
}

上面第一行粗体字代码使用了@Service注解修饰该实现类,且该类位于org.crazyit.firstboot.service.impl包下,也就是位于FirstbootApplication类所在包的子包下,因此SpringBoot会自动扫描该实现类,并将它配置成容器中的Bean。

上面第二行粗体字代码使用了@Transaction注解修饰该Service组件,该注解指定事务传播规则为REQUIRED,事物超时时长为5秒,Spring将会为该Service组件生成事物代理,从而为该Service组件中的每个方法都添加事务。为目标组件生成事务代理是Spring AOP的功能,但生成事务代码所需要的事务管理器,同样由SpringBoot自动配置提供。

上面第三行粗体字代码使用了@Autowired注解修饰符BookDao实例变量,这也是Spring的基本用法,Spring将会把容器中唯一的、类型为BookDao的Bean注入该实例变量。

下面修改后的BookController类的代码

@Controller
public class BookController
{
	@GetMapping("/")
	public String index(Model model)
	{
	model.addAttribute("tip","欢迎访问第一个SpringBoot应用");
	return "hello";
	}


	@GetMapping("/rest")
	@ResponseBody
	public ResponseEntity restIndex()
	{
		return new ResponseEntity<>("欢迎访问第一个springboot应用",null,HttpStatus.OK);
	}

	@Autowired
	private BookService bookService;

	@PostMapping("/addBook")
	public String addBook(Book book,Model model)
	{
		bookService.addBook(book);
		return "redirect:listBooks";
	}

	@PostMapping("/rest/books")
	@ResponseBody
	public ResponseEntity> restAddBook(@RequestBody Book book)
	{
		bookService.addBook(book);
		return new ResponseEntity<>(Map.of("tip","添加成功"),null,HttpStatus.Ok);
	}

	@GetMapping("/listBooks")
	public String list(Model model){
		model.addAttribute("books",bookService.getAllBooks());
		return "list";
	}

	@GetMapping("/rest/books")
	@ResponseBody
	public ResponseEntity> restList()
	{
		return new ResponseEntity<>(bookService.getAllBooks(),null,HttpStatus.OK);
	}
	
	@GetMapping("/deleteBook")
	public String delete(Integer id)
	{
		bookService.deleteBook(id);
		return "redirect:listBooks";
	}
	
	@DeleteMapping("/rest/books/{id}")
	@ResponseBody
	public ResponseEntity> restDelete(@PathVariable Integer id)
	{
		bookService.deleteBook(id);
		return new ResponseEntity<>(Map.of("tip","删除成功"),null,HttpStatus.OK);

	}

}

上面的BookController类增加了一个BookService实例变量,且使用了@Autowired注解修饰,因此Spring会将容器中唯一的、类型为BookService的Bean注入该实例变量。

接下来该BookController定义了6个处理方法,这些处理方法使用了@GetMapping、@PostMapping、@DeleteMapping等注解修饰,映射这些处理方法能处理来自不同URL地址的请求。这些注解都属于Spring MVC的基本注解,并不属于SpringBoot。

上面这些方法定义了两个版本,带界面响应的版本和Restful版本,使用@ResponseBody修饰的方法就是用于生成Restful响应的方法。

对于RESTful响应的处理方法,Spring Boot应用无须提供视图页面,在前后端分离的架构中,前端应用会负责提供用户界面、处理用户交互。SpringBoot应用主要暴露RESTful接口即可。

对于要生成界面的处理方法,程序还需要为它们提供视图页面。首先在前面的hello.html页面中增加一个表单,该表单供用户填写图书信息,修改后的hello.html页面代码如下。

在这里插入代码片

上面页面添加了一个Bootstrap样式的表单,该表单的界面看起来会比较美观,该表单的提交地址是addBook,与前面BookController中处理方法定义的处理地址对应。
还需要一个list.html页面用于显示所有图书,该页面代码如下:

在这里插入代码片
十三、开发DAO组件

前面BookService中用到了BookDao组件和Boolk类,这些都是与持久化相关的类,本例直接使用SpringBoot Data JPA来访问数据库,为此首先要为项目添加如下依赖:

  • SpringBoot Data JPA依赖
  • MySQL数据库驱动依赖

增加下面两个依赖:


	org.springframework.boot
	spring-boot-starter-data-jps


	mysql
	mysql-connector-java
	runtime

添加了上面依赖后,重新加载项目依赖库,然后在项目的srcmainapplication目录下添加一个application.properties文件,这个文件是SpringBoot项目的配置文件,当整合不同的项目时,该配置文件支持大量不同的属性,不同的属性也由不同的类处理类负责读取。

#数据库url地址
sparing.datasource.url=jdbc:mysql://localhost:3306/springboot?serverTimezone=UTC
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=32147
#指定显示SQL语句
spring.jpa.show-sql=true
#指定根据实体自动建表
spring.jpa.generate-ddl=true

上面配置文件指定了连接数据库的基本信息:URL地址、用户名和密码,并指定了JPA能根据实体类自动建表,还会显示所执行的SQL语句。

为项目创建一个Book实体类,该实体类代码如下:
firstbookdomainBook.java

@Entity
@Table(name="book_inf")
public class Book
{
	@Id
	@Column(name="book_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String title;
	private String author;
	private double price;
	//省略getter、setter方法
}

配置文件指定了连接数据库的基本信息,SpringBoot将会自动在容器中配置一个DataSource Bean,SpringBoot将会自动在容器中配置一个EntityManagerFactory Bean。

为项目创建DAO组件:BookDao,该DAO组件接口代码如下:

public interface BookDao extends CrudRepository
{
}

该BookDao接口完全是一个空接口,仅仅继承了CrudRepository,实际上已经拥有了大量方法。得益于Spring Data的优秀设计,集成了CrudRepository接口的BookDao不需要提供实现类,Spring Data会自动为它动态生成实现类,并将给实现类的实例部署在Spring容器中,Spring Data还可为BookDao动态增加很多查询方法。

该应用还提供了RESTful接口,可使用Postman来测试RESTful接口。使用Postman向"http://localhost:8080/rest/books"发送GET请求

十三、编写单元测试 1.测试RESTful接口

SpringBoot提供了@SpringBootTest注解,该注解用于修饰单元测试用例类。测试用例的测试方法依然使用@Test或@ParameterizedTest注解修饰。


	org.springframework.boot
	spring-boot-starter-test
	test

该依赖就是指SpringBoot单元测试的依赖库,由于该依赖又依赖JUnit 5.x,因此添加该依赖会自动添加JUnit5依赖。

controllerRandomPortTest.java

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
public class RandomPortTest
{
	@Autowired
	private TestRestTemplate restTemplate;
	@Test
	public void testIndexRest()
	{
		//测试restIndex方法
		var result = restTemplate.getForObject("/rest",String.class);
		Assertions.assertEquals("欢迎访问第一个SpringBoot应用")
	}

	@ParameterizedTest
	@CsvSource({"java,fy,180","python,py,160"})
	public void testRestAddBook(String title,String author,double price)
	{
		var book =new Book(title,author,price);
		//测试restAddBook方法
		var result = restTemplate.postForObject("/rest/books",book,Map.class);
		Assertions.assertEquals(result.get("tip"),"添加成功");		
	}

	@Test
	public void testRestList()
	{
		//测试restList方法
		var result = restTemplate.getForObject("/rest/books",List.class);
		result.forEach(System.out::println);
	}
	@ParameterizedTest
	@ValueSource(ints={4,5})
	public void testRestDelete(Integer id){
		//测试restDelete方法
		restTemplate.delete("/rest/books/{0}",id);
	}
}

上面测试用例类使用了@SpringBootTest注解yt.RANDOM_PORT,这表示在运行测试时,将会为Web服务器随机分配端口。

上面测试方法有的使用了@Test修饰,有的使用了@ParameterizedTest修饰,后者是JUnit 5.x新增的测试注解,用于表示参数化测试。@ValueSource、@CsvSource等注解提供的参数来调用参数化测试方法。

上面的测试用例中依赖注入了一个TestRestTemplate对象,这个TestRestTemplate对象实际上是对Resttemplate进行了封装,可以在测试环境中更方便地使用RestTemplate的功能,因此TestRestTemplate主要用于测试RESTful接口的功能。

上面的@SpringBootTest注解指定了webEnvironment = WebEnvironment.RANDOM_PORT,不需要知道web服务器端口是多少,可以直接进行测试。如果想使用固定端口,可以将webEnvironment属性指定为WebEnvironment.DEFINED_PORT,这样SpringBoot就会读取项目配置文件中的端口来启动Web服务器,若没有配置的话,默认值为8080端口

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/273929.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号