liudehaos

还历史以真诚,还生命以过程。 ——余秋雨
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SpringBoot

Posted on 2022-05-18 20:37  liudehaos  阅读(159)  评论(0编辑  收藏  举报

SpringBoot的引言

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的 初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不 再需要定义样板化的配置。通过这种方式,Spring Boot致力于在蓬勃发展的快速应 用开发领域(rapid application development)成为领导者。

Spring Boot 全新框架 作用: 简化spring应用初始搭建和开发过程

如何简化: 开发人员使用springboot只要基于特定方式进行配置 简化spring使用

SpringBoot 微框架: 5分钟 完成之前ssm中环境

springboot(微框架) = springmvc(控制器) + spring core(项目管理)

SpringBoot的优势

  1. 创建完整的独立的Spring应用程序 spring springmvc 只有一个容器

  2. 嵌入的Tomcat,无需部署WAR文件 springboot 内嵌tomcat 应用跑在内嵌服务器

  3. 简化Maven配置,自动配置Spring Springmvc,没有XML配置 几个依赖

    1. 用来springboot spring应用在无xml

SpringBoot的约定

springboot 基于maven做的(前提保证maven是装好并且IDEA配置好的)(面向接口编程)
  约定:
  1、springboot项目约定springboot项目中有且仅有一个入口类(class),类名:推荐 xxx(项目名)Application.java
      a. 入口类必须放在所有子包之上
      b. 入口类中必须有一个启动项目的main方法
  2、springboot项目必须在项目的根目录中存在一个名字为application.yml 或者叫 application.properties 配置文件
      名字必须是以application开头

项目架构:
  src/main/java
          com.shujia.
                      .entity     实体类
                      .dao       主要存放对数据做操作的实现类
                      .service   接口层
                      .controller 存放是页面与后端交互的接口层
                      Application.java   -------------> 入口类 有且只有一个
  src/main/resource   运行时配置文件
                  application.yml
                  //
                  application.properties
  src/test/java       测试java代码
  src/test/resource   测试配置文件

 

  • springboot 项目中必须在src/main/resources中放入application.yml(.properties)核心配置文件 名字必须为:application

     

  • springboot 项目中必须在src/main/java中所有子包之外构建全局入口类型,xxApplication,入口类一个springboot项目只能有一个

环境搭建

环境要求

# 1.System Requirements
JDK1.8+
MAVEN3.2+
Spring Framework 5.x+
springboot 2.5.0

# 2.ServletContainers:
Tomcat 9.0+

# 3.开发工具
IDEA 2021版本
最近使用idea 社区版发现不支持直接创建spring boot 程序,搜索发现需要安装spring-assistant 插件。但在idea直接搜索并 没有此插件。
后面了解到:
idea社区版 不支持 spring BOOT ,需要插件 ntellij-spring-assistant 。
官方插件库的spring-assistant 只支持到idea 2020.3 版本以前。

# SpringBoot三种搭建方式

1.maven手动搭建

2.通过IDEA搭建(最常用,也是最迅速的搭建方式,前提是网络要好,很容易出现网络不好的情况,可以使用下面的第三种方式)

IDEA社区版事不支持spring boot程序,搜索发现需要安装spring-assistant 插件。但在idea直接搜索并 没有此插件。

 

 

 

 

3.通过官网进行搭建(在第二种网络出现不好的情况下使用,--通过观察一般下午的时间段网络容易崩打不开)

网址是:https://start.spring.io/

环境搭建

环境要求
# 1.System Requirements
JDK1.8+
MAVEN3.2+  
Spring Framework 5.x+
springboot 2.5.0

# 2.ServletContainers:
Tomcat 9.0+

# 3.开发工具
IDEA   2021版本
最近使用idea 社区版发现不支持直接创建spring boot 程序,搜索发现需要安装spring-assistant 插件。但在idea直接搜索并 没有此插件。
后面了解到:
idea社区版 不支持 spring BOOT ,需要插件 ntellij-spring-assistant 。
官方插件库的spring-assistant 只支持到idea 2020.3 版本以前。
新建项目中引入依赖
    <!--继承springboot的父项目-->
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.5.0</version>
   </parent>

   <dependencies>
    <!--引入springboot的web支持-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
   </dependencies>
引入配置文件

项目中 src/main/resources/application.yml

编写入口类
//在项目中如下的包结构中创建入口类 Application
/*
com
+| shujia
*/
   @SpringBootApplication
   public class Application {
     public static void main(String[] args) {
       SpringApplication.run(Application.class,args);
    }
  }
运行main启动项目
o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
com.baizhi.Application : Started Application in 2.152 seconds (JVM running for 2.611)
//说明: 出现以上日志说明启动成功

注意:到这里项目环境已经搭建成功了,看看仅仅需要5分钟

建包并创建控制器
//在项目中创建指定的包结构
/*
com
   +| shujia
  +| controller */
              @Controller
                 @RequestMapping("/hello")
                 public class HelloController {
                   @RequestMapping("/hello")
                   @ResponseBody
                   public String hello(){
                    System.out.println("======hello world=======");
                     return "hello";
                  }
                }
               
访问项目
# 注意: springboot的项目启动默认项目名
- 访问路径: http://localhost:8080/hello/hello
修改内嵌服务器端口
server:
port: 8989
修改应用名称
server:
servlet:
  context-path: /springboot_day1

相关注解说明

注解:从JDK5开始,Java增加对元数据的支持,也就是注解,注解与注释是有一定区别的,可以把注解理解为代码里的特殊标记,这些标记可以在编译,类加载,运行时被读取,并执行相应的处理。通过注解开发人员可以在不改变原有代码和逻辑的情况下在源代码中嵌入补充信息。

# 入口类 SpringApplication
- SpringBootApplication: 全局入口类 有且只能有一个
- mian 函数参数可以在启动时指定jvm参数覆盖默认配置

# @SpringBootApplication 注解等价于:
- @SpringBootConfiguration           标识这是一个springboot的配置类,默认自定配置Spring环境
- @EnableAutoConfiguration 自动与项目中集成的第三方技术进行集成
- @ComponentScan 扫描入口类所在子包以及子包后代包中注解

配置文件

配置文件的拆分

说明: 在实际开发过程中生产环境和测试环境有可能是不一样的 因此将生产中的配置和测试中的配置拆分开,是非常必要的在springboot中也提供了配置文件拆分的方式. 这里以生产中项名名称不一致为例:

image-20220510105058398

  • 生产中项目名为: springboot

  • 测试中项目名为: springboot_day1

  • 端口同时为: 8080

# 主配置文件:
- application.yml #用来书写相同的的配置
server:
port: 8080 #生产和测试端口一致
                 
# 生产配置文件:
- application-pord.yml #prod为配置文件简名
  server:
  context-path: /cmfz
   
#测试配置文件:
- application-dev.yml  #dev为配置文件简名
  server:
  context-path: /springboot

#在主配置中指定那个环境生效配置
spring:
profiles:
  active: dev #指定那个环境配置生效 dev为环境配置文件的简名

image-20220509221122788

启动指定配置文件

说明: 往往在企业级开发过程中为SpringBoot应用启动时指定一个完整外部配置也是经常用到的,在SpringBoot中也提供这个方式来启动项目如:

# 1.创建一个完整的配置文件

image-20220509221738558

# 2.启动时指定配置文件位置

image-20220509221714322


工厂创建对象

创建单个对象

在springboot中可以管理单个对象可以直接使用spring框架中注解形式创建。

  • @Component 通用的对象创建注解

    • @Controller 用来创建控制器对象

    • @Service 用来创建业务层对象

    • @Repository 用来创建DAO层对象

      • 以上注解都有value属性,value属性用来指定工厂中对象名称

@Service
public class DemoServiceImpl implements UserService{
 //doing....
}
# 2.通过工厂创建之后可以在使用处注入该对象
@Controller
@RequestMapping("hello")
public class HelloController {
   @Autowired
   private DemoService demoService;
   //doing...
}

创建多个对象

如何在springboot中像spring框架一样通过xml创建多个对象,在SpringBoot中也提供了相同注解如@Configuration + @Bean注解进行创建

  • @Configuration 代表这是一个spring的配置类相当于Spring.xml配置文件

  • @Bean 用来在工厂中创建这个@Bean注解标识的对象

    • 默认使用@Bean创建对象在工厂中唯一标识为方法名称

    • 修改在工厂中对象标识可以在使用@Bean("工厂中名字")指定一个名字

# 1.管理复杂对象的创建
@Configuration
public class Beans {
   @Bean
   public Calendar calendar(){
       return Calendar.getInstance();
  }
}
# 2.使用复杂对象
@Controller
@RequestMapping("hello")
public class HelloController {
   @Autowired
   private Calendar calendar;
  ......
}
# 注意: 
1.@Configuration 用来在工厂中一次性创建多个对象
 2.@Component     用来创建单个对象                    

属性注入

基本属性注入
# 1.@Value 属性注入               [重点]
@RestController
public class HelloController {
   //基本类型+String类型+日期类型
@Value("${name}")
   private String name;
   @Value("${age}")
   private Integer age;
   @Value("${sex}")
   private Boolean sex;
   @Value("${price}")
   private Double price;
   @Value("${bir}")
   private Date bir;
//注入数组
   @Value("${qqs}")
   private String[] qqs;
//注入list
   @Value("${lists}")
   private List<String> lists;
//注入maps
   @Value("#{${maps}}")
   private Map<String,String> maps;
}
# 2.在配置文件中定义注入值
name: 小虎
age: 23
price: 23.23
sex: true
bir: 2012/12/12

qqs: 123,3434,3434
lists: xiaochen,xiaoming,xiaosan

maps: "{'aa':'1234','bb':'2344'}"
  • 注意: 这里面map集合注入比较特殊

对象方式注入

注意: 这种方式必须提供SET方法

# 1. @ConfigurationProperties(prefix="前缀")
@Component
@ConfigurationProperties(prefix = "user")
public class User {
   private String id;
   private String name;
   private Integer age;
   private String  bir;
   //set 方法一定要提供
}
# 2. 编写配置文件
user:
id: 24
name: xiaohei
age: 23
bir: 2012/12/12
# 3. 引入依赖构建自定义注入元数据  不加也行
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-configuration-processor</artifactId>
 <optional>true</optional>
</dependency>

JSP模板集成

在SpringBoot框架中默认模板推荐使用Thymeleaf模板,这里我们优先讲与JSP模板集成

在main中手动的建webapp文件夹,放jsp文件

引入jsp的集成jar包
<!--c标签库-->
<dependency>
   <groupId>jstl</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
</dependency>

<!--让内嵌tomcat具有解析jsp功能-->
<dependency>
   <groupId>org.apache.tomcat.embed</groupId>
   <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
引入jsp运行插件(最新的版本不用引入)
<build>
   <finalName>springboot-demo2</finalName>
   <!--引入springboot插件 可以正确打包 显示jsp-->
   <plugins>
       <plugin>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-maven-plugin</artifactId>
       </plugin>
   </plugins>
</build>
配置视图解析器
#在配置文件中引入视图解析器
spring:
mvc:
  view:
    prefix: /     # /代表访问项目中webapp中页面
    suffix: .jsp
第一种方式使用插件启动访问JSP页面

image-20191129124602959

第二种方式使用idea中指定工作目录启动 访问JSP

image-20220510001158894

启动项目测试
http://localhost:8083/jsp
修改jsp无须重启应用
server:
servlet:
  jsp:
    init-parameters:
      development: true

SpringBoot链接MySQL

在学习任何一个后端技术,如果不让数据库参与进来,那只能说在学习过程中都不算完整的。下面就简单的使用Spring Boot链接MySQL数据库。该例子中没有使用其他的持久化框架,只是使用到了Spring自带的JdbcTemplate。

1、引入MySQL依赖

<!--添加MySql依赖-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>

2、引入Spring JDBC依赖

<!--添加JDBC依赖-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

3、配置MySQL链接

属性配置文件:

mysql.url=jdbc:mysql://192.168.40.110:3306/scott
mysql.username=root
mysql.password=123456

SpringBoot配置文件:

server:
port: ${rest.port}
context-path: /sbm/
tomcat:
  uri-encoding: UTF-8
spring:
datasource:
  driver-class-name: com.mysql.jdbc.Driver
  url: ${mysql.url}
  username: ${mysql.username}
  password: ${mysql.password}

4、创建Service类

package com.shujia.service;

import com.shujia.Bean.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public class DeptServiceImpl implements DeptService{
   @Autowired
   private JdbcTemplate jdbcTemplate;

   @Override
   public List<Dept> getAllCusBaseInfo() {
       //查询部门信息
       List<Map<String,Object>> list=jdbcTemplate.queryForList("select * from dept");
       List<Dept> cusBaseInfoList=new ArrayList<>();
       for (Map<String,Object> map:list ) {
           Dept cusBaseInfo=new Dept();
           //部门id
           cusBaseInfo.setDeptno(map.get("deptno").toString());

           cusBaseInfo.setDname(map.get("dname").toString());

           cusBaseInfo.setLoc(map.get("loc").toString());
           cusBaseInfoList.add(cusBaseInfo);
      }
       return cusBaseInfoList;
  }

   @Override
   public Dept saveDeptInfo(Dept dept) {
       dept.setDeptno(UUID.randomUUID().toString());
       String sql="insert into deptno(deptno,dname,loc) values(?,?,?)";
       jdbcTemplate.update(sql,new Object[]{dept.getDeptno(),
               dept.getDname(),
               dept.getLoc(),},new int[]{Types.VARCHAR,Types.VARCHAR,Types.VARCHAR});
       //获取信息
       return getDeptByNo(dept.getDeptno());
  }

   @Override
   public Dept getDeptByNo(String deptNo) {
       Map<String,Object> map=jdbcTemplate.queryForMap("select * from cus_base_info where cus_id = ?",deptNo);
       Dept cusBaseInfo=new Dept();
       
       cusBaseInfo.setDeptno(map.get("deptno").toString());
     
       cusBaseInfo.setDname(map.get("dname").toString());
       
       cusBaseInfo.setLoc(map.get("loc").toString());
       return cusBaseInfo;
  }
}

5、创建Controller类

package com.shujia.controller;

import com.shujia.Bean.Dept;
import com.shujia.service.DeptServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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;

@RestController
@RequestMapping(value = "/cus")
public class DeptController {

   @Autowired
   private DeptServiceImpl deptService;

   /**
    * 获取所有客户信息
    * @return
    */
   @RequestMapping(value = "/all",method = RequestMethod.GET)
   public List<Dept> getAllCusBaseInfo(){
       return deptService.getAllCusBaseInfo();
  }

   /**
    * 保存客户信息
    * @param dept
    * @return
    */
   @RequestMapping(value = "/save",method = RequestMethod.POST)
   public Dept saveCusBaseInfo(Dept dept){
       return deptService.saveDeptInfo(dept);
  }

   /**
    * 根据客户ID查询客户信息
    * @param deptno
    * @return
    */
   @RequestMapping(value = "/get/{cusId}",method = RequestMethod.GET)
   public Dept getCusBaseInfoById(@PathVariable String deptno){
       return deptService.getDeptByNo(deptno);
  }
}

日志处理

引言

springboot框架 集成日志 logback 日志

Logback是由log4j创始人设计的又一个开源日志组件。目前,logback分为三个模块:logback-core,logback-classic和logback-access。是对log4j日志展示进一步改进!

总结: logback 也是一个开源日志组件 和 log4j作用一致 都是用来生成日志 logback更加轻量

日志的级别

image-20210610110653288

> All < Trace < `DEBUG < INFO < WARN < ERROR` < Fatal < OFF

- OFF   | 关闭:最高级别,不打印日志。
- FATAL | 致命:指明非常严重的可能会导致应用终止执行错误事件。
- ERROR | 错误:指明错误事件,但应用可能还能继续运行。
- WARN | 警告:指明可能潜在的危险状况。
- INFO | 信息:指明描述信息,从粗粒度上描述了应用运行过程。
- DEBUG | 调试:指明细致的事件信息,对调试应用最有用。
- TRACE | 跟踪:指明程序运行轨迹,比DEBUG级别的粒度更细。
- ALL | 所有:所有日志级别,包括定制级别。

> 日志级别由低到高:  `日志级别越高输出的日志信息越多`
项目中日志分类
# 日志分类:
- 一种是rootLogger(根全局日志) :     用来监听项目中所有的运行日志 包括引入依赖jar中的日志

- 一种是logger(指定包级别日志) :         用来监听项目中指定包中的日志信息
配置日志

注意:SpringBoot框架中默认根日志为INFO

logging:
level:
  root: debug #指定根日志级别(一般不推荐修改根日志,输出信息太多,推荐使用子日志)
  com.baizhi.dao: debug #指定某个包中日志
file:
  name: aaa.log #指定日志名称
  path: ./  #指定日志文件目录
项目中使用日志
@Controller
public class HelloController {
   //声明日志成员
   private static final Logger log = LoggerFactory.getLogger(HelloController.class);
   @RequestMapping("/hello")
   @ResponseBody
   public String hello(){
       System.out.println("======hello world=======");
       log.debug("DEBUG,{}","信息");
       log.info("INFO,{}","信息");
       log.warn("WARN,{}","信息");
       log.error("ERROR,{}","信息");
       return "hello";
  }
}

Thymeleaf

Thymeleaf是一个用于web和独立环境的现代服务器端Java模板引擎。

--摘自官网https://www.thymeleaf.org/

Thymeleaf是跟Velocity、FreeMarker类似的模板引擎,它可以完全替代JSP,相较与其他的模板引擎相比, Thymeleaf在有网络和无网络的环境下皆可运行,即它可以让美工在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数据的动态页面效果。

集成Thymeleaf模板
引入依赖
<!--使用thymelaf-->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
编写配置
spring:
thymeleaf:
  cache: false  # 关闭缓存
  prefix: classpath:/templates/ #指定模板位置
  suffix: .html #指定后缀
编写控制器测试

@Controller    //一定要是@Controller 不能再使用@RestController注解
@RequestMapping("hello")
public class HelloController {
   @GetMapping("hello")
   public String hello(){
       System.out.println("测试与 thymeleaf 的集成");
       return "index";
  }
}
在templates目录中定义模板

image-20200323085834206

测试访问
http://localhost:8989/springboot_day3/hello/hello
查看结果

image-20200323085948499


模板基本语法
使用时必须在页面中加入thymeleaf如下命名空间:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
展示单个数据
设置数据
model.addAttribute("name","张三"); request.setAttribute("name","小黑");
获取数据
<span th:text="${name}"/>  --->获取数据

image-20200323100747881

解析含有html标签数据
model.addAttribute("name","<a href=''>张三</a>");
model.addAttribute("username","小陈");
  • 直接获取原样输出

<span th:text="${name}"/>

image-20200323100956740

  • 获取并解析

 <span th:utext="${name}"/>

image-20200323101457134

  • 将数据赋值给表单元素

    <input type="text" th:value="${username}"/>

    image-20200323103452620

     

# 总结
-  1.使用 th:text="${属性名}" 获取对应数据,获取数据时会将对应标签中数据清空,因此最好是空标签
-  2.使用 th:utext="${属性名}" 获取对应的数据,可以将数据中html先解析在渲染到页面
-  3.使用 th:value="${属性名}" 获取数据直接作为表单元素value属性
展示对象数据
model.addAttribute("user",new User("21","xiaochen",23,new Date()));
id:<span th:text="${user.id}"></span>
name:<span th:text="${user.name}"></span>
age:<span th:text="${user.age}"></span>
bir: <span th:text="${user.bir}"></span> ====  <span th:text="${#dates.format(user.bir, 'yyyy-MM-dd HH:mm')}"></span> 日期格式化
条件展示数据
model.addAttribute("user",new User("21","xiaochen",23,new Date()));
<span th:if="${user.age} eq 23">
青年
</span>
<span th:if="${user.age == 23}">
青年
</span>
# 运算符
  gt:great than(大于)>
  ge:great equal(大于等于)>=
  eq:equal(等于)==
  lt:less than(小于)<
   le:less equal(小于等于)<=
  ne:not equal(不等于)!=
展示多条数据
  • 直接遍历集合

 <ul th:each="user:${users}">
   <li th:text="${user.id}"></li>
   <li th:text="${user.name}"></li>
   <li th:text="${user.age}"></li>
   <li th:text="${#dates.format(user.bir,'yyyy-MM-dd')}"></li>
</ul>
  • 遍历时获取遍历状态

 <ul th:each="user,userStat:${users}">
  <li><span th:text="${userStat.count}"/>-<span th:text="${user.id}"/></li>   获取遍历次数 count 从1开始 index 从0开始
  <li><span th:text="${userStat.odd}"/>-<span th:text="${user.name}"/></li>   获取当前遍历是否是奇数行
  <li><span th:text="${userStat.even}"/>-<span th:text="${user.age}"/></li>   获取当前遍历是否是偶数行
  <li><span th:text="${userStat.size}"/>-<span th:text="${user.bir}"/></li>   获取当前集合的总条数
</ul>
引入静态资源
# 使用thymeleaf模板项目中静态资源默认放在resources路径小static目录中
  • 项目中放入对应静态资源

    image-20200323142307411

  • 页面中引入

     <link rel="stylesheet" th:href="@{/css/index.css}">
    <script th:src="@{/js/jquery-min.js}"></script>

    注意: @{/}代表通过thymeleaf语法动态获取应用名

在js代码中获取项目名
<script>
 const ctx = '[[@{/}]]';
</script>

注意:[[书写thymeleaf语法]],这里[[]]是thymeleaf内嵌表达式

总结

学习的目标:

1、知道springboot项目三种创建方式

2、知道springboot项目配置文件是如何修改的,掌握课上的修改方式即可

3、掌握分层

entity ---->存放实体类 比如Dept 不同的程序员这个实体类层名字叫法可能不太一样 pojo bean po

controller -------> 写控制类,与网页url做请求交互的 ------> 最后是以页面做交互的(JSP,thymeleaf(HTML5))

sercvice ----------> 主要放接口,功能接口没有具体实现

dao ---------------> 主要存放对数据库的操作,如果是对sercvice层接口实现并且操作了数据库,也可以放在这一层

configs ------------> 主要存放配置类的

utils ---------------> 专门存放工具类的

4、掌握数据的在层与层之间的传输(springboot的项目执行流程)

5、可以额外的学习一下,表单,表格,拦截器,JS(了解)

创建spring boot的三种方式

1、用IDEA手动创建maven项目

2、使用链接-创建模板

https://start.spring.io/

3用IDEA创建spring boot项目