初识Spring Boot(Spring Boot基础学习)

Spring Boot基础

学习目标:

  1. 能够理解 Spring 的优缺点
  2. 能够理解 Spring Boot 的特点
  3. 能够理解 Spring Boot 的核心功能
  4. 能够搭建 Spring Boot 的环境
  5. 能够完成 application.properties 配置文件的配置
  6. 能够完成 application.yml 配置文件的配置
  7. 能够使用 Spring Boot 集成 Mybatis
  8. 能够使用 Spring Boot 集成 Junit
  9. 能够使用 Spring Boot 集成 Spring Data JPA

一、Spring Boot 简介

1.1 原有 Spring 优缺点分析

1.1.1 Spring 的优点分析

  • Spring 是Java企业版(Java Enterprise Edition 也称J2EE)的轻量级替代品,无需开发重量级的Enterprise JavaBean(EJB),Spring 为企业版Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object POJO)实现了 EJB 的功能

1.1.2 Spring 的缺点分析

  • Spring 的组件代码是轻量级的,但它的配置确实重量级的。Spring1.0 使用的是XML配置,而且是很多的XML配置;Spring2.0 引入了基于注解的组件扫描,这消除了大量针对应用程序自身组建的显式XML配置;Spring3.0 引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以完全代替XML。
  • Spring 开发过程中,由于思考 Spring 特性配置和解决业务问题之间的思维切换,导致开发时间的损耗。
  • 项目依赖的管理,在项目环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库坐标,一旦选错了依赖的版本,那随之而来的不兼容问题会严重阻碍项目的开发进度。

1.2 Spring Boot 的概述

1.2.1 Spring Boot 解决上述 Spring 的缺点

  • Spring Boot 是对 Spring 缺点进行的改善和优化,基于约定优于配置的思想。

1.2.2 Spring Boot 的特点

  • 为基于 Spring 的开发提供更快的入门体验
  • 开箱即用,没有代码生成,也无需XML配置,同时也可以修改默认值来满足特定的需求
  • 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全指标、健康检测、外部配置等
  • Spring Boot 不是对 Spring 功能上的增强,而是提供了一种更快速的使用 Spring 的方式

1.2.3 Spring Boot 的核心功能

  • 起步依赖
    • 简单来说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
  • 自动配置
    • Spring Boot 的自动配置是一个运行时(更准确的说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring 配置应该用哪个,不应该用哪个。该过程是 Spring 自动完成的。

二、Spring Boot 快速入门

2.1 代码实现

2.1.1 创建 Maven 工程

  • 使用IDEA创建一个 Maven 工程,该工程为普通的 java 工程即可。

2.1.2 添加Spring Boot的起步依赖

  • Spring Boot 要求,项目要继承 Spring Boot 的起步依赖 spring-boot-starter-parent

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.1.0.RELEASEversion>
parent>
  • Spring Boot 要集成 SpringMVC 的 Controller 进行开发,所以项目要导入 web 的启动依赖
<dependencies>
    
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
dependencies>

2.1.3 编写 Spring Boot 的引导类

  • 要通过 Spring Boot 提供的引导类起步 Spring Boot 才可以进行访问
package com.guojh;

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

/**
 * Spring Boot项目用于启动的引导类
 */
@SpringBootApplication
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class);
    }

}

2.1.4 编写 Controller

  • 在引导类 SpringBootApplication 同级包或者子级包中创建类 QuickController
package com.guojh.Controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class QuickController {

    @RequestMapping("quick")
    @ResponseBody
    public String quick() {
        return "Hello SpringBoot!";
    }

}

2.1.5 测试

  • 地址栏输入:http://localhost:8080/quick 访问

2.2 快速入门解析

2.2.1 Spring Boot 代码解析

  • Spring Boot的常用注解:https://www.cnblogs.com/tanwei81/p/6814022.html

2.2.2 Spring Boot 工程热部署

  • 在 pom.xml 中添加如下代码,在进行 Spring Boot 开发时候可以实现热部署

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-devtoolsartifactId>
dependency>
  • 注意:IDEA进行 Spring Boot 热部署失败的原因
  1. 出现这种情况并不是热部署配置的问题,其原因使 Spring Boot 不自动编译的问题,需要对IDEA进行自动编译的设置
  • 初识Spring Boot(Spring Boot基础学习)_第1张图片
  1. 按住Ctrl+Shift+Alt+/ 选择Registry
  • 初识Spring Boot(Spring Boot基础学习)_第2张图片
  • 初识Spring Boot(Spring Boot基础学习)_第3张图片

2.2.3 使用IDEA快速创建 Spring Boot 项目

三、Spring Boot 原理分析

3.1 起步依赖原理分析

3.1.1 分析 spring-boot-starter-parent

  1. 按住Ctrl点击 pom.xml 中的 spring-boot-starter-parent,跳转到了 spring-boot-starter-parent 的 pom.xml 中,XML配置如下:
<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-dependenciesartifactId>
    <version>2.1.0.RELEASEversion>
    <relativePath>../../spring-boot-dependenciesrelativePath>
parent>
  1. 按住Ctrl点击 pom.xml 中的 spring-boot-dependencies,跳转到了 spring-boot-dependencies 的 pom.xml 中,XML配置如下:
<properties>
    <activemq.version>5.15.7activemq.version>
    <antlr2.version>2.7.7antlr2.version>
    <appengine-sdk.version>1.9.67appengine-sdk.version>
    <artemis.version>2.6.3artemis.version>
    <aspectj.version>1.9.2aspectj.version>
    <assertj.version>3.11.1assertj.version>
    <atomikos.version>4.0.6atomikos.version>
	.......
properties>

3.1.2 分析 spring-boot-starter-web

  1. 查看 pom.xml 中的 web 起步依赖 spring-boot-starter-web

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-webartifactId>
dependency>
  1. 依赖中包含 spring-boot-starterspring-boot-starter-jsonspring-webspring-webmvc 等,查看 json 依赖,如下(部分信息):
<dependency>
    <groupId>org.springframeworkgroupId>
    <artifactId>spring-webartifactId>
    <version>5.1.2.RELEASEversion>
    <scope>compilescope>
dependency>
<dependency>
    <groupId>com.fasterxml.jackson.coregroupId>
    <artifactId>jackson-databindartifactId>
    <version>2.9.7version>
    <scope>compilescope>
dependency>

3.2 自动配置原理解析

  • 查看 Spring Boot 引导类中的注解:@SpringBootApplication
  • @SpringBootApplication 注解包括 @SpringBootConfiguration (其注解为 @Configuration 等同于 spring 的XML配置文件)、@EnableAutoConfiguration (表示开启自动化配置)、@ComponentScan (用于组件扫描)
  • Spring Boot 常用注解:Spring Boot 常用注解解析

四、Spring Boot 配置文件

4.1 Spring Boot 配置文件类型

4.1.1 Spring Boot 配置文件类型和作用

  • Spring Boot 是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用 application.properties 或者 application.yml (application.yaml) 进行配置。
  • Spring Boot 默认会从 Resources 目录下加载 application.properties 或者 application.yml (application.yaml) 文件
    • 其中 application.properties 文件是键值对类型的文件。

4.1.2 application.yml 配置文件

4.1.2.1 yml 配置文件简介

  • YML 文件格式是 YAML(YAML Aint Markup Language) 编写的文件格式,YAML 是一种直观的能够被电脑识别的数据序列化格式,并且容易被人阅读,容易和脚本语言交互,可以被支持 YAML 库的不同的编程语言程序导入,如:C/C++、Ruby、Python、Java、Perl、C#、PHP等,YML 文件是以数据为核心的,比传统的 XML 方式更加简洁。
  • (注:YML 文件的扩展名可以使用 .yml.yaml
<resource>
    <filtering>truefiltering>
    <directory>${basedir}/src/main/resourcesdirectory>
    <includes>
        <include>**/application*.ymlinclude>
        <include>**/application*.yamlinclude>
        <include>**/application*.propertiesinclude>
    includes>
resource>
  • (配置文件由上至下优先级提高)

4.1.2.2 yml 配置文件的语法(用缩进/空格方式来代替层级关系)

4.1.2.2.1 配置普通数据
  • 语法:key: value
  • 示例代码:
name: huasir
  • (注:name:+空格 value之前有一个空格)
4.1.2.2.2 配置对象数据
  • 语法:
  • key:
    • key1: value1
    • key2: value2
    • key3: value3
  • 或者:key: {key1: value1,key2: value2,key3: value3}
  • 示例代码:
# 对象数据的配置
person:
  name: huasir
  age: 18
  addr: shanxi

# 行内对象配置 --此种配置在实际开发中使用的很少
person: {name: huasir,age: 18,addr: shanxi}
  • (注:在yml语法中,相同的缩进代表同一级别)
4.1.2.2.3 配置Map数据
  • 同 4.1.2.2.2 配置对象数据
4.1.2.2.4 配置数组(List、Set)数据
  • 语法:
  • key:
    • -value1
    • -value2
    • -value3
  • 或者:key: [value1, value2, value3]
  • 示例代码:
# 配置集合数据(普通字符串)
city:
  - beijing
  - shanghai
  - chongqing

city: [beijing, shanghai, chongqing]

# 配置集合数据(对象数据)
student:
  - name: zhangsan
    age: 18
    addr: shanxi
  - name: lisi
    age: 19
    addr: beijing
    
student: [{name: zhangsan, age: 18, addr: shanxi},{name: lisi, age: 19, addr: beijing}]

4.2 配置文件与配置类的属性映射方式

4.2.1 使用注解 @Value 映射

  • 我们可以通过 @Value 注解将配置文件中的值映射到一个 Spring 管理的 Bean 字段上
  • 例如:
  • application.yml 配置如下:
# 普通数据的配置
name: huasir


# 对象数据的配置
person:
  name: huasir
  age: 18
  addr: shanxi
  • 实体 Bean 代码如下:
package com.guojh.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
public class Quick2Controller {

    @Value("${name}")
    public String name;

    @Value("${person.addr}")
    public String addr;

    @RequestMapping("quick2")
    @ResponseBody
    public String quick2() {
        return "yml获取普通数据的配置name:" + name + "——addr:" + addr;
    }

}

4.2.2 使用注解 @ConfigurationProperties 映射

  • 我们通过注解 @ConfigurationProperties(prefix=“配置文件中的key的前缀”) 可以将配置文件中的配置自动与实体进行映射
  • 例如:
  • application.yml 配置如下:
# 对象数据的配置
person:
  name: huasir
  age: 18
  addr: shanxi
  • 实体 Bean 代码如下:
package com.guojh.controller;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/")
@ConfigurationProperties(prefix = "person")
public class Quick3Controller {

    private String name;
    private Integer age;
    private String addr;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @RequestMapping("quick3")
    @ResponseBody
    public String quick3() {

        return "yml对象数据的配置结果如下:name: " + name + "...age: " + age + "...addr: " + addr;

    }

}	
  • 配置注解 @ConfigurationProperties 的执行器

<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-configuration-processorartifactId>
    <optional>trueoptional>
dependency>

五、Spring Boot 整合其他技术

5.1 Spring Boot 整合 Mybatis

5.1.1 添加 Mybatis 起步依赖


<dependency>
    <groupId>org.mybatis.spring.bootgroupId>
    <artifactId>mybatis-spring-boot-starterartifactId>
    <version>1.3.1version>
dependency>

5.1.2 添加数据库驱动坐标

<parent>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-parentartifactId>
    <version>2.2.4.RELEASEversion>
    <relativePath/> 
parent>
  • 初识Spring Boot(Spring Boot基础学习)_第4张图片


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.25version>
dependency>
  • 此处如果本机使用的是 Mysql8,在添加 MySQL 依赖的时候不需要添加版本号 5.1.25
  • 解决:添加 MySQL 版本号,或者降低 Spring Boot 的版本号

5.1.3 添加数据库连接信息

  • application.properties 中配置数据库的连接信息
# 数据库连接信息
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

5.1.4 创建user表

  • 在 test 数据库中创建 user 表
DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`username`,`password`,`name`) 
            values (1,'zhangsan','zs123','张三'),
                   (2,'lisi','ls123','李四'),
                   (3,'wangwu','ww123','王五'),
                   (4,'zhaoliu','zl123','赵六');

5.1.5 创建实体 Bean

  • 导入 lombok 相关依赖

<dependency>
    <groupId>org.projectlombokgroupId>
    <artifactId>lombokartifactId>
dependency>

package com.guojh.springbootmybatis.domain;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

@Data
@Getter
@Setter
public class User {

    private Integer id;
    private String username;
    private String password;
    private String name;


    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                '}';
    }

}

5.1.6 编写Mapper

package com.guojh.springbootmybatis.mapper;

import com.guojh.springbootmybatis.domain.User;

import java.util.List;

@Mapper
public interface UserMapper {

    public List<User> queryUserList();

}

5.1.7 配置Mapper映射文件




<mapper namespace="com.guojh.springbootmybatis.mapper.UserMapper">
    <select id="queryUserList" resultType="user">
        select * from user
    select>
mapper>

5.1.8 在application.properties中添加mybatis的信息

# 配置Mybatis中的信息
# pojo别名扫描包
mybatis.type-aliases-package=com.guojh.springbootmybatis.domain
# 加载Mybatis映射文件
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

5.1.9 编写测试类Controller

package com.guojh.springbootmybatis.controller;

import com.guojh.springbootmybatis.domain.User;
import com.guojh.springbootmybatis.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("/")
public class MybatisController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping("queryUserList")
    @ResponseBody
    public List<User> queryUserList() {
        List<User> userList = userMapper.queryUserList();
        return userList;
    }

}
  • 注解 @Autowired@Resource 的区别 参考博客:参考博客1,参考博客2
    • @Resource 的作用相当于 @Autowired,只不过 @Autowired 按照 byType 自动注入,@Resource 按照 byName 自动注入。

5.2 Spring Boot 整合 Junit

5.2.1 添加 Junit 起步依赖


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-testartifactId>
    <scope>testscope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintagegroupId>
            <artifactId>junit-vintage-engineartifactId>
        exclusion>
    exclusions>
dependency>

5.2.2 编写测试类

package com.guojh.springbootmybatis;


import com.guojh.springbootmybatis.domain.User;
import com.guojh.springbootmybatis.mapper.UserMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootMybatisApplication.class)
public class MybatisTest {

    @Resource
    private UserMapper userMapper;

    @Test
    public void test() {
        List<User> userList = userMapper.queryUserList();
        System.out.println(userList);
    }

}

5.3 Spring Boot 整合 Spring Data JPA

5.3.1 添加 Spring Data JPA 起步依赖


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-jpaartifactId>
dependency>

5.3.2 添加数据库驱动依赖


<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.25version>
dependency>

5.3.3 在application.properties中配置数据库和jpa的相关属性

# 数据库连接信息
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

# JPA 的相关配置信息
spring.jpa.database=mysql
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update

5.3.4 创建实体配置实体

package com.guojh.domain;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Data
@Getter
@Setter
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String username;
    private String password;
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}

5.3.5 编写UserRepository

package com.guojh.repository;

import com.guojh.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface UserRepository extends JpaRepository<User, Integer> {

    @Override
    public List<User> findAll();

}

5.3.6 编写测试类

package com.guojh;


import com.guojh.domain.User;
import com.guojh.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJpaApplication.class)
public class JPATest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void test() {
        List<User> userList = userRepository.findAll();
        System.out.println(userList);
    }

}
  • 注意:使用 jdk9 会提示:NoClassDefFoundError: javax/xml/bind/JAXBException
  • 解决办法:添加如下依赖

<dependency>
    <groupId>javax.xml.bindgroupId>
    <artifactId>jaxb-apiartifactId>
    <version>2.3.0version>
dependency>

5.4 Spring Boot 整合 Redis

5.4.1 添加 Redis 起步依赖


<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
dependency>

5.4.2 配置 Redis 的连接信息

# redis 配置信息
spring.redis.host=192.168.38.144
spring.redis.port=6379
  • 在Linux中安装Redis参考博客:Linux安装Redis

5.4.3 注入 RedisTemplate 测试 Redis 操作

package com.guojh;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.guojh.domain.User;
import com.guojh.repository.UserRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJpaApplication.class)
public class RedisTest {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserRepository userRepository;

    @Test
    public void test() throws JsonProcessingException {
        // 1、从 Redis 中获得数据没数据的形式为JSON字符串格式
        Object userList = redisTemplate.boundValueOps("user.findAll").get();
        // 2、判断Redis中是否存在数据
        if (null == userList) {
            // 3.不存在数据 从数据库查询
            List<User> all = userRepository.findAll();
            // 4.将查询出来的数据放入Redis 缓存中
            // 先将list集合转换成JSON格式的字符串 使用jackson进行转换
            ObjectMapper objectMapper = new ObjectMapper();
            userList = objectMapper.writeValueAsString(all);
            redisTemplate.boundValueOps("user.findAll").set(userList);

            System.out.println("======== 从数据库中获得user数据 ========");

        } else {

            System.out.println("======== 从Redis缓存中获得user数据 ========");

        }

        // 5、控制台打印输出JSON格式的数据
        System.out.println(userList);

    }

}

你可能感兴趣的:(java,javaweb,java,spring,spring,boot)