博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot入门和使用实践
阅读量:4298 次
发布时间:2019-05-27

本文共 10507 字,大约阅读时间需要 35 分钟。

目录

SpringBoot入门和使用实践

一、软件环境

  • JDK 1.8+
  • Maven 3.2.5+
  • PostMan (www.getpostman.com)

二、简介

  • Springboot角色
Spring Cloud(构建Spring Boot的分布式环境) |Spring Boot(快速构建Spring的应用)   |Spring Framework (底层,Java EE框架)
  • Spring Boot 2.x.x 新特性
编程语言:Java 8+、Kotlin底层框架:Spring Framework全新特性:Web Flux(传统Spring应用使用标签或注解来描述请求或响应的映射,web flux支持声明式、函数式编程)
  • 为什么选择Web Flux
函数编程:Java 8 Lambda响应编程:Reactive Streams(java 9 Flow API、Reactive Extensions-RXjava、Reactor)异步编程:Servlet 3.1 或 Asyc NIO
  • 2.0 特性
  1. 自动装配:MVC、JDBC、事务等组件的装配

  2. 内置容器:Tomcat、Jetty等

  3. DevOps:针对生产的开发运维模式

三、使用

1、第一个springboot项目

  1. 编写 Rest 程序
  2. 运行 Spring Boot 应用
  3. 使用 HTTP 请求工具:PostMan
  4. 场景说明:
  • 定义用户模型,包括属性:用户ID和名称
  • 客户端发送 Post 请求,创建用户 (Web MVC)
  • 客户端发送 GET 请求,获取所有用户(Web Flux)
  • Map 存储数据

1)进入 start.spring.io

  • 网址:
  1. Project 选择 Maven Project
  2. Language 选择 Java
  3. Spring Boot 选择 2以上的版本
  4. Group 填写:com.test
  5. Artifact 填写:first-app-demo
  6. Depencies 填写:Reactive Web
  7. 点击 Generate Project 下载项目

2)解压项目,使用 IDEA 加载项目

3)创建文件夹和类

  1. domain文件夹,创建User类,定义id和name属性(get\set\toString)
package com.test.firstappdemo.domain;/** * * 用户模型 * */public class User {
private int id; private String name; public int getId() {
return id; } public void setId(int id) {
this.id = id; } public String getName() {
return name; } public void setName(String name) {
this.name = name; } @Override public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + '}'; }}
  1. repository文件夹,创建UserRepository类(@Repository、Java doc注释、public boolean save(User user) 、ConcurrentMap<Interger,User>、AtomicInteger)
package com.test.firstappdemo.repository;import com.test.firstappdemo.domain.User;import org.springframework.stereotype.Repository;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import java.util.concurrent.atomic.AtomicInteger;/** * {@link User} {@link @Repository} * */@Repositorypublic class UserRepository {
//内存型保存方式 private final ConcurrentMap
userRepostory = new ConcurrentHashMap<>(); private final static AtomicInteger idGenerator = new AtomicInteger(); /** * 保存对象 * @param user {@link User} 对象 * @return 如果保存成功,返回
true * 否则,返回
false * */ public boolean save(User user){
//从1开始 Integer id = idGenerator.incrementAndGet(); user.setId(id); return userRepostory.put(id, user) == null; }}
  1. controller文件夹,创建UserController类(@RestController、构造器注入UserRepository、@PostMapping、public User save(@RequestParam String name))
package com.test.firstappdemo.controller;import com.test.firstappdemo.domain.User;import com.test.firstappdemo.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class UserController {
// 注入用户仓储,构造器注入好处:不能修改,提前初始化 private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository; } @PostMapping("/person/save") public User save(@RequestParam String name){
User user = new User(); user.setName(name); if(userRepository.save(user)){
System.out.printf("用户对象:%s 保存成功.\n", user); } return user; }}

4) 运行启动类

  • 启动类名称:<项目名称+Application>,debug启动(启动后可查看Spring Boot版本和PID,web flux默认使用Netty容器进行启动)

  • PostMan:POST请求 【http://localhost:8080/person/save】 ;属性设置 name=zcheng

5)GET请求,查询所有用户

  • UserRepository
package com.test.firstappdemo.repository;import com.test.firstappdemo.domain.User;import org.springframework.stereotype.Repository;import java.util.Collection;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentMap;import java.util.concurrent.atomic.AtomicInteger;/** * {@link User} {@link @Repository} * */@Repositorypublic class UserRepository {
//内存型保存方式 private final ConcurrentMap
userRepostory = new ConcurrentHashMap<>(); private final static AtomicInteger idGenerator = new AtomicInteger(); /** * 保存对象 * @param user {@link User} 对象 * @return 如果保存成功,返回
true * 否则,返回
false * */ public boolean save(User user){
//从1开始 Integer id = idGenerator.incrementAndGet(); user.setId(id); return userRepostory.put(id, user) == null; } public Collection
values() {
return userRepostory.values(); }}
  • UserController
package com.test.firstappdemo.controller;import com.test.firstappdemo.domain.User;import com.test.firstappdemo.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import java.util.Collection;@RestControllerpublic class UserController {
// 注入用户仓储,构造器注入好处:不能修改,提前初始化 private UserRepository userRepository; @Autowired public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository; } @PostMapping("/person/save") public User save(@RequestParam String name){
User user = new User(); user.setName(name); if(userRepository.save(user)){
System.out.printf("用户对象:%s 保存成功.\n", user); } return user; } @GetMapping("/person/findAll") public Collection
findAll(){
return userRepository.values(); }}
  • PostMan:GET请求【http://localhost:8080/person/findAll】

6)实现 Web Flux

  • spring 官网介绍 1.8章 Reactive Libraries
  • 传统NIO实现的Reactor模式,是同步非阻塞,Spring的Reactor是Reactive的实现,是异步非阻塞
  • Mono表示(0:1)的对象,类似Java 8的 Optional,防止空指针,查询 Mono 到 1.5.1 HandlerFunction
  • Flux表示(0:N)的对象,类似一个集合,空集合或包含很多元素
  • MVC使用@RequestMapping进行映射,Web Flux 使用函数式编程声明接口,Spring 5之后将Servlet接口进行封装
  • 通过路由函数定义类似@RequestMapping的映射
package com.test.firstappdemo.config;import com.test.firstappdemo.domain.User;import com.test.firstappdemo.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.reactive.function.server.RequestPredicates;import org.springframework.web.reactive.function.server.RouterFunction;import org.springframework.web.reactive.function.server.RouterFunctions;import org.springframework.web.reactive.function.server.ServerResponse;import reactor.core.publisher.Flux;import reactor.core.publisher.Mono;import java.util.Collection;/** * 路由器函数 * *///从Spring 3开始逐渐使用Configuration代替xml文件@Configurationpublic class RouterFunctionConfiguration {
/** * Servlet: * 请求接口:ServletRequest 或者 HttpServletRequest * 响应接口:ServletResponse 或者 HttpServletResponse * Spring 5.0 重新定义了服务的请求和响应: * 请求接口:ServerRequest * 响应接口:ServerResponse * 请求和响应接口既支持Servlet的规范,也可以自定义规范,比如:Netty(Web Server) * Reactive中的Flux 或 Mono 它是异步处理(非阻塞) * 集合对象基本上是同步处理(阻塞) * Flux 或 Mono 都是 Publisher(发布者)推模式来推送数据 * Web Flux通过异步的方式提高吞吐量 * 1.5 Functional Endpoints 介绍函数式的端点(Rest暴露) * 1.5.2 RouterFunction 查看例子 * */ /** * 场景: * 定义GET请求,并且返回所有的用户对象 URL:/person/find/all * 依赖仓储对象,@Autowired 可以不加,只是表明 仓储是方法注入 * * */ @Bean @Autowired public RouterFunction
personFindAll(UserRepository userRepository){
// 定义映射关系,一般s结尾都是静态类或工具类,lamda表达式,request是方法参数 // HandlerFunction参数是ServerRequest,返回Mono return RouterFunctions.route(RequestPredicates.GET("/person/find/all"), request -> {
// 获取所有对象 Collection
users = userRepository.values(); //集合对象转Flux对象 Flux
userFlux = Flux.fromIterable(users); return ServerResponse.ok().body(userFlux, User.class); }); }}

2、构建方式

  • 图形化构建:http://start.spring.io
  • Maven
  1. Apache Maven官网:http://maven.apache.org/archetype/maven-archetype-plugin/generate-mojo.html

    // interactiveMode=false表示非交互式

  2. Windows -> CMD窗口:mvn archetype:generate -DinteractiveMode=false -DgroupId=com.test -DartifactId=first-app-demo -Dversion=1.0.0-SNAPSHOT

    // 查看文件目录

    $ dir

  3. https://spring.io/guides/gs/rest-service/ 找到 Build with Maven,复制 pom.xml 配置

    // IDEA 弹窗 Enable Auto Import

    // 默认生成的jUnit测试工具,去掉版本号,因为Spring的父工程中已经存在版本控制

  4. 然后配置启动类和控制类,和之前的内容一样

3、多模块项目

  • 重构
  • 调整主(父)工程(由jar变为子项目的管理)

  • 创建子模块工程()

    模块层:model(domain)

    持久层:presistence(repository)

    表示层:web(controller)

  • 子模块依赖管理()

  • 具体操作
  1. 修改pom.xml(有可能最后删除src时,IDEA会自动添加,所以这一步可以尝试忽略)

    pom

  2. 创建 maven 子模块

    a. web -> presistence -> model 由高往低创建

    b. 项目名称 -> New -> Module -> 不选择archetype -> artifactId填写 web -> Finish

    c. 如果web的src中java和resources未标记文件夹类型(没问题的直接跳过)

    • java 文件夹 -> 右键 -> Mark Directory as -> Sources Root
    • resources 文件夹 -> 右键 -> Mark Directory as -> Resources Root
    • test 文件夹 -> 右键 -> Mark Directory as -> Test Sources Root

    d. 迁移代码

    • 子模块创建 java 文件夹创建 com.test(这一步要看IDEA版本给不给直接拖到)

    • 选择父项目的 java 下的内容 com.xxx.xxx 拖到 web 子模块的 java文件夹中

    • Move everything from

    • Yes -> Continue

    • 选择父项目的 resources 下的内容,拖到 web 子模块的 resources文件夹中

    • 删除父项目的src文件夹

    • 运行启动类

    • 接下来根据上面步骤,把其它子模块也进行重构

    • presistence pom.xml 设置 model 依赖;复制model pom.xml

    • web pom.xml 设置 presistence 依赖;复制presistence pom.xml

    • IDEA 头部菜单 -> Build -> Build Project -> 运行启动类

  • 微服务中应用的服务职责或权限职责要单一

4、打包和运行

  • 打包方式
  • 构建 JAR 包
  • 构建 WAR 包
  • 构建 Main-Class

1)构建 jar 包

  • 父pom.xml文件添加main-class:(进入启动类 -> 选中类名右键 -> copy Reference)

    org.springframework.boot
    spring-boot-maven-plugin
    com.test.firstappdemo.FirstAppDemoApplication
  • 将上面父pom.xml 内容剪切到web子模块的pom.xml中

    // 跳过测试,更新第三方包

  • cmd窗口(IDEA Terminal):项目名称 -> 右键 -> copy path -> cd 项目路径 -> mvn -Dmaven.test.skip -U clean package

  • 或者 使用IDEA右侧菜单的Maven Projects的LifeCycle

  • cmd窗口(IDEA Terminal):cd web -> cd target -> java -jar web-0.0.1-SNAPSHOT.jar

2) 构建 war 包

  • web子模块添加目录 src/main/webapp/WEB-INF/web.xml

  • web pom.xml文件新增或修改

    // 默认jar

    war
  • cmd窗口(IDEA Terminal):cd web -> cd target -> java -jar web-0.0.1-SNAPSHOT.war

3) 运行模式

  • IDEA 方式(开发调试)
  • JAR/WAR 方式(一般线上)
  • Maven 插件方式(极端)
  1. cmd窗口(IDEA Terminal):项目根目录 -> mvn -Dmaven.test.skip -U clean install

  2. cmd窗口(IDEA Terminal):cd web -> mvn spring-boot:run

转载地址:http://zknws.baihongyu.com/

你可能感兴趣的文章
python爬虫 CSS选择器
查看>>
正常关闭java程序
查看>>
查看linux核心数
查看>>
数据结构与算法三: 数组
查看>>
Activiti工作流会签二 启动流程
查看>>
Activiti工作流会签三 撤销,审批,驳回
查看>>
Oauth2方式实现单点登录
查看>>
CountDownLatch源码解析加流程图详解--AQS类注释翻译
查看>>
ES相关度评分
查看>>
我们一起做一个可以商用的springboot脚手架
查看>>
idea在搭建ssm框架时mybatis整合问题 无法找到mapper
查看>>
java设计基本原则----单一职责原则
查看>>
HashMap的实现
查看>>
互斥锁 synchronized分析
查看>>
java等待-通知机制 synchronized和waity()的使用实践
查看>>
win10 Docke安装mysql8.0
查看>>
docker 启动已经停止的容器
查看>>
order by 排序原理及性能优化
查看>>
Lock重入锁
查看>>
docker安装 rabbitMq
查看>>