Bootstrap

Spring Boot (入门 起步依赖原理 配置 整合其他框架)

SpringBoot 概述

SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻
辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度
上缩短了项目周期。2014 年 4 月,Spring Boot 1.0.0 发布。Spring的顶级项目之一(https://spring.io)。

Spring 缺点

1) 配置繁琐
虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,Spring用XML配置,而且是很多
XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。
Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。
所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所
以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但它要求的回报也不少。
2)依赖繁琐
项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导
入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发
进度。

SpringBoot 功能

1) 自动配置
Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定
Spring配置应该用哪个,不该用哪个。该过程是SpringBoot自动完成的。
2) 起步依赖
起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖
,这些东西加在一起即支持某项功能。
简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。
3) 辅助功能
提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等。

一、入门

依赖

    <!--springboot工程需要继承的父工程-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
    </parent>

    <dependencies>
        <!--web开发的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

2,启动类

@SpringBootApplication
public class HelloApplication {

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

二、SpringBoot起步依赖原理分析

  • 在spring-boot-starter-parent中定义了各种技术的版本信息,组合了一套最优搭配的技术版本。

  • 在各种starter中,定义了完成该功能需要的坐标合集,其中大部分版本信息来自于父工程。

  • 我们的工程继承parent,引入starter后,通过依赖传递,就可以简单方便获得需要的jar包,并且不会存在版本冲突等问题。

三、SpringBoot配置-配置文件分类

SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。

  1. 默认配置文件名称:application

  2. 在同一级目录下优先级为:properties>yml > yaml

例如:配置内置Tomcat的端口

properties:

server.port=8080

yml:

server: port: 8080

SpringBoot配置-yaml基本语法

  • 大小写敏感
  • 数据值前边必须有空格,作为分隔符
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键,只允许使用空格(各个系统Tab对应的空格数目可能不同,导致层次混乱)
  • 缩进的空格数目不重要,只有相同层级的元素左侧对齐即可
  • #表示注释,从这个字符串一直到行尾,都会被忽略
server: 
	port: 8080  
    address: 127.0.0.1
name: abc

SpringBoot配置-yaml数据格式

对象(map):键值对的集合。

person:  
   name: zhangsan
# 行内写法
person: {name: zhangsan}

数组:一组按次序排列的值

address:
  - beijing
  - shanghai
# 行内写法
address: [beijing,shanghai]

纯量:单个的、不可再分的值

msg1: 'hello \n world'  # 单引忽略转义字符
msg2: "hello \n world"  # 双引识别转义字符

参数引用

name: lisi 
person:
  name: ${name} # 引用上边定义的name值

SpringBoot配置-获取数据

1.@Value注入
在这里插入图片描述
2.Evironment

@Autowired
 private Environment env;

System.out.println(env.getProperty("person.name"));

 System.out.println(env.getProperty("address[0]"));

3.@ConfigurationProperties
在这里插入图片描述
1、可以写在类上,通过@Autowired注入即可
2、写在配置文件中,加入这一段,也是一样通过bean,@Autowired注入

SpringBoot配置-项目内部配置文件加载顺序

加载顺序为上文的排列顺序,高优先级配置的属性会生效

  • file:./config/:当前项目下的/config目录下
  • file:./ :当前项目的根目录
  • classpath:/config/:classpath的/config目录
  • classpath:/ :classpath的根目录

二、静态页面位置

因为是jar文件,那就很奇怪静态页面放哪了?
查询配置文件的源码发现,已经定义了一个位置具体放的位置
在这里插入图片描述
这些路径都能放,classpath路径下,也就是 resources这个目录下,都是可以访问的,如有加pages或者包,记得拼接上去

在这里插入图片描述

三、拦截器

在这里插入图片描述

需要配置两个类,一个类实现HandlerInterceptor接口,实现preHandle方法,变成拦截器类,另一个类当做配置类,配置进mvc容器中

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("-------------");
        return true;
    }
}

@Configuration
public class MyInter implements WebMvcConfigurer {

    @Bean
    public HandlerInterceptor getInter(){
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(getInter()).addPathPatterns("/**");
    }
}

四、配置

Springboot配置文件名称必须是以application开头

在这里插入图片描述

六、多环境开发

在这里插入图片描述
分为两个,一种是只写一个配置文件,用三个横线—来区分位置,但文件多了会乱,第二种是每个环境写一个单独的配置文件,注意名字前缀必须是application开头,点properties结尾,中间加写内容。
这些文件要使用的时候要记得激活,才能使用。
图中profile要加s

配置文件可以写在多个地方,外部的优先级大于内部的,根目录大于classpath的,config里大于外的,如果有则按优先级最高的使用,忽略其他,如果没有则补充进来
在这里插入图片描述

七、整合其他框架

注意一点,引导的位置很重要,因为它的会自动包扫描,扫描同级和它的子包

junit

依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

在这里插入图片描述
springboot: 2.1.x版本

@RunWith(SpringRunner.class)
@SpringBootTest(classes = HelloApplication.class)//如果测试类和启动类在同一个包下classes属性可以不写。如果不是就要指定启动类的字节码对象
public class BootTest {

    @Autowired
    private UserService userService;

    @Test
    public void testJunit(){
        System.out.println(userService.test());
    }
}

springboot : 2.2.x版本

@SpringBootTest
class BootTest {

    @Autowired
    private UserService userService;

    @Test
    public void testJunit(){
        System.out.println(userService.test());
    }

}

Mybatis和事务

依赖

<dependencies>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

数据库连接和包扫描,起别名还是要的。application.properties或者.yml啥的地方写

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://11111:3306/springboot
    username: root
    password: root


mybatis:
  type-aliases-package: com.ybb.domain
  mapper-locations: classpath:mapper/*Mapper.xml

实体类

public class User {
    private int id;
    private String username;
    private String password;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

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

dao和mapper

@Mapper
@Repository
public interface UserXmlMapper {

    public List<User> findAll();
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.springbootmybatis.mapper.UserXmlMapper">
    <select id="findAll" resultType="user">
        select * from t_user
    </select>
</mapper>

或者

@Mapper
@Repository
public interface UserMapper {

    @Select("select * from t_user")
    public List<User> findAll();
}

redis

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
    </dependencies>
  redis:
    host: 127.0.0.1
    port: 6379

如果有修改端口和访问地址,记得修改,其他默认即可

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

    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void testSet() {
        //存入数据
        redisTemplate.boundValueOps("name").set("zhangsan");
    }

    @Test
    public void testGet() {
        //获取数据
        Object name = redisTemplate.boundValueOps("name").get();
        System.out.println(name);
    }

    @Test
    public void testAll() {
        //string 字符串
        //redisTemplate.opsForValue().set("str", "heima");
        redisTemplate.boundValueOps("str").set("heima");
        System.out.println("str = " + redisTemplate.opsForValue().get("str"));

        //hash 散列
        redisTemplate.boundHashOps("h_key").put("name", "heima");
        redisTemplate.boundHashOps("h_key").put("age", 13);
        //获取所有域
        Set set = redisTemplate.boundHashOps("h_key").keys();
        System.out.println(" hash散列的所有域:" + set);
        //获取所有值
        List list = redisTemplate.boundHashOps("h_key").values();
        System.out.println(" hash散列的所有域的值:" + list);

        //list 列表
        redisTemplate.boundListOps("l_key").leftPush("c");
        redisTemplate.boundListOps("l_key").leftPush("b");
        redisTemplate.boundListOps("l_key").leftPush("a");
        //获取全部元素
        list = redisTemplate.boundListOps("l_key").range(0, -1);
        System.out.println(" list列表中的所有元素:" + list);

        // set 集合
        redisTemplate.boundSetOps("s_key").add("a", "b", "c");
        set = redisTemplate.boundSetOps("s_key").members();
        System.out.println(" set集合中的所有元素:" + set);

        // sorted set 有序集合
        redisTemplate.boundZSetOps("z_key").add("a", 30);
        redisTemplate.boundZSetOps("z_key").add("b", 20);
        redisTemplate.boundZSetOps("z_key").add("c", 10);
        set = redisTemplate.boundZSetOps("z_key").range(0, -1);
        System.out.println(" zset有序集合中的所有元素:" + set);
    }

}

MyBatis Plus

    <dependencies>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>


        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <!--<scope>runtime</scope>-->
        </dependency>

        <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        </dependency>
    </dependencies>

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://121/plus
    username: root
    password: root

mapper

package com.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.domain.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * Description :
 * Version :1.0
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

启动类

package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * Description :
 * Version :1.0
 */
@SpringBootApplication
@MapperScan("com.mapper")
public class xxxpp {
    public static void main(String[] args) {
        SpringApplication.run(xxxApp.class,args);
    }
}

Test

package com;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.domain.User;
import com.mapper.UserMapper;
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 javax.sql.DataSource;
import java.sql.SQLException;
import java.sql.Wrapper;
import java.util.List;

/**
 * Description :
 * Version :1.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ybbApp.class)
public class SampleTest {


    @Autowired
    private UserMapper userMapper;

    @Test
    public void test1() throws SQLException {

     /*   System.out.println(dataSource.getConnection());*/
        /*List<User> users = userMapper.selectList(null);
        for (User user : users) {
            System.out.println(user);
        }*/

    /*    userMapper.insert(new User(6,"aa",22,"test6#"));
*
     */

    /*    QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("name","aa");
        List<User> users = userMapper.selectList(userQueryWrapper);
        for (User user : users) {
            System.out.println(user);
        }*/

        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("id",1);
        userMapper.delete(userUpdateWrapper);

    }
}

;