SpringBoot学习_day1

Spring Boot的了解以及快速入门

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。因为我们知道,Spring开发的时候,我们需要创建他的配置文件,并且还需要导入许多的坐标,并且可能会因为各个坐标之间的版本原因从而导致不兼容,从而出现报错等。正因为spring的配置相对繁琐,所以就产生了Spring Boot,它简化了Spring的配置,Spring Boot简化了配置,并且SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决

参考资料:Spring Boot

关于Spring Boot的快速入门,可以参考这一篇文章:IDEA搭建Spring Boot

Spring Boot的配置文件

在Spring Boot的配置文件中,可以是xxx.properties,也可以是xxx.yml或者xxx.yaml。其中文件名一般是application.其中在propertes配置文件中的格式应该如下所示:

service.port=8080

而在yml或者yaml中的格式为:

# port是在server下一层,所以需要换行,并且需要空出几格,类似于文件目录以树型结构的形式呈现出来是一样的道理
server: 
   port: 8080 # 键和值之间需要有空格隔开,否则就会发生报错的

所以在yml或者yaml中的格式要求为:
在这里插入图片描述

值得一提的是,在同一个目录下面给,优先级是:properties > yml > yaml,所以如果三个配置文件中设置了相同的属性的时候,那么会选择优先级较高的配置文件。例如如果三个配置文件都分别设置了端口值,那么Spring Boot就会选择优先级高的application.properties的文件的值

在yml中,如果需要设置对象的属性,那么它的格式和上面设置server.port的格式是类似的,例如我们需要设置person这个属性中name以及age的属性的时候,那么对应的配置格式应该是:

person:
   name: zhangshan # 键和值之间同样需要有空格间隔开
   age: 20  # 因为name和age都是person的属性,所以是在同一层,因此age和name是左边对齐的

如果需要设置设置数组的元素的值,那么需要以下面的格式进行定义:

array: 
  - zhangshan # 以一个符号开始,然后空格,之后再写它的元素值
  - lisi    

如果值被单引号或者双引号括起来的时候,那么这时候两者的形式是不同的。单引号括起来的字符串中如果含有特殊字符,那么它是不会进行转义的,即它是原样输出的,但是如果是双引号括起来的字符串,那么它是能够对特殊字符进行转义的

同样的,我们可以在配置文件中利用spring表达式${xxx}来引用xxx属性的值

所以如果我们需要获取xxx.yml配置文件中的属性的值的时候,我们可以有3种方式:

  • 利用@Value注解,通过在对应的成员上方写上@Value("${xxx}"),这样就可以利用spring表达式,将获取到配置文件中xxx属性的值了,然后再赋值给修饰的成员。但是,如果是这样写@Value("xxx"),这样就是直接给修饰的成员赋值xxx,作用等同于成员名=xxx**。
  • 利用@Autowired注解,从spring容器中取出Environment对象,通过调用方法getProperty("xxx"),就会获取到了配置文件中xxx属性的值了。值得注意的是,这个Environment对象是一个接口,是在org.springframework下面的。
  • 利用注解@ConfigurationProperties

测试代码为:

application.yml代码:

server:
  port: 8081

# 在yml中表示对象的时候,那么先定义一个父对象,然后再设置父对象的属性的值
person:
  name: zhangshan
  age: 20

# 表示数组的时候,那么先定义数组的名字,然后再下一行,先用一个`-`开始,再空一格空格,后面就是它的元素值
array:
  - aaa
  - bbb
  - ccc

# 单值形式的字符串,如果是一个单引号的字符串,那么就是原样输出,不会转义特殊字符
# 如果是双引号的字符串,那么他会转义特殊字符。例如
# 'Hello \n world' ----> 原样输出
# "Hello \n world" ----> 转义特殊字符\n,所以会换行打印,输出
#  Hello
#   world
msg1: 'Hello \n world'
msg2: "Hello \n world"

# 如果需要引用某一个属性的值的时候,需要利用${}表达式,其中花括号就是我们需要引用的属性名
msg3: ${msg1}

对应的测试类:

@Controller //将当前这个类添加到bean容器中
public class HelloController {
    @Value("msg1") //这样写的话,是将字符串msg1赋值给msg1,效果等于String msg1 = "msg1";
    private String msg1;

    @Value("${msg2}") //将配置文件中的属性msg2的值通过spring表达式获取,然后将它的值赋值给msg2
    private String msg2;

    @Value("${msg3}")
    private String msg3;

    @RequestMapping("/hello")
    @ResponseBody //提示返回值适用于回写数据的,而不是用于页面跳转的
    public String hello(){
        System.out.println(msg1);
        System.out.println("-----------------");
        System.out.println(msg2);
        System.out.println("-----------------");
        System.out.println(msg3);
        return "Hello !!! Spring Boot !!!";
    }
}

当我们开始运行之后,在搜索框上面输入localhost:8080/hello,(因为还在application.properties文件中设置了端口为8080),那么就会在控制台下打印下面的结果:
在这里插入图片描述

但是当我们利用希望获取配置文件中数组的值的时候,即如果执行@Value("${array}"),这时候就会发生报错的,如下所示:
在这里插入图片描述

但是当我们将配置文件中的数组array改成这样写的时候,就可以正常运行了:array: aaa,bbb,ccc(注意值和属性名之间有空格间隔开)。代码如下所示:

@Controller //将当前这个类添加到bean容器中
public class HelloController {
    @Value("${array}") //将配置文件中属性为array的值赋值给array数组以及字符串msg4
    private String[] array;
    @Value("${array}")
    private String msg4;

    @RequestMapping("/hello")
    @ResponseBody //提示返回值适用于回写数据的,而不是用于页面跳转的
    public String hello(){
        System.out.println(Arrays.asList(array) + ", " + array.length);
        System.out.println(msg4);
        return "Hello !!! Spring Boot !!!";
    }
}

这时候,如果在搜索框输入localhost:8080/hello,那么就会在控制台输出如下信息:

[aaa, bbb, ccc], 3
aaa,bbb,ccc

具体原因不是很理解,但是个人觉得是配置文件中的属性array的值就是一个字符串,然后再赋值给数组的时候,是根据分隔符,进行分割,从而形成了长度为3的字符串数组,因为当我们将array属性的值改称为aaa.bbb.ccc的时候,那么这时候控制台中输出的数组长度就是1,元素的值就只有aaa.bbb.ccc。

同样的,如果我们希望利用注解@Value来获取people属性的值的时候,同样会发生上面的错误信息,提示Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'person' in value "${person}",因为@Value是用于注入普通的数据类型的,而没有办法注入Bean对象的。所以这时候我们只能注入person下面的属性值,即@Value("${person.name}")等形式是可以成功注入的。

当我们利用@Autowired注解的时候,我们可以从spring容器中取出Environment的Bean对象,然后通过调用getProperty(“xxx”),就可以获取到属性为xxx的值了。测试代码如下所示:

@Controller //将当前这个类添加到bean容器中
public class HelloController {
    @Autowired
    private Environment environment;

    @RequestMapping("/test")
    @ResponseBody
    public String test(){
        String msg1 = environment.getProperty("msg1");
        System.out.println(msg1);
        System.out.println("---------------------");
        String msg2 = environment.getProperty("msg2");
        System.out.println(msg2);
        System.out.println("---------------------");
        return "通过从Bean对象中取出Environment对象,调用getProperty方法来获取配置文件中的属性值";
    }
}

对应的结果为:

Hello \n world
---------------------
Hello 
 world
---------------------

同样的,如果我们需要获取数组等属性的值的时候,对应代码为:

@Controller //将当前这个类添加到bean容器中
public class HelloController {
    @Autowired
    private Environment environment;

    @RequestMapping("/test")
    @ResponseBody
    public String test(){
        Person person = environment.getProperty("person", Person.class); //尽管希望获取person属性,然后封装到Person类中,但是这时候返回的person为null
        System.out.println(person);
        System.out.println("---------------------");
        String[] arrays = environment.getProperty("array", String[].class);//这时候的array属性的值在配置文件中为array: aaa,bbb,ccc
        System.out.println(Arrays.asList(arrays));
        return "通过从Bean对象中取出Environment对象,调用getProperty方法来获取配置文件中的属性值";
    }
}

输出结果为:

null
---------------------
[aaa, bbb, ccc]

但是如果在配置文件中array的格式是按照这样写的时候:

array:
   - aaa
   - bbb
   - ccc

那么这时候,即使是通过Environment对象调用getProperty(“array”,String[].class),也会发生报错,提示java.lang.IllegalArgumentException: Could not resolve placeholder 'array' in value "${array}".

利用注解@ConfigurationProperty(prefix = "xxx"),这样就会将配置文件中的属性为xxx的元素赋值给它修饰的类,这样就可以将这个xxx属性中的成员的值赋值给这个类中相同名字的成员。然后再利用相关的注解,例如@Component,将这个类添加到Spring容器中,这样我们就可以直接利用@Autowired来获取这个类了。例如上面配置文件中的person属性,无论是@Value,还是通过Environment对象调用getProperty方法,都没有办法直接返回Person对象,而这种方式则可以。对应的代码为:

@Component //添加到Spring容器种
//配置文件中扫描person属性,这样就可以将它的子属性赋值给当前这个类中相同名字的成员
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

测试代码:

@Controller //将当前这个类添加到bean容器中
public class HelloController {
    @Autowired
    private Person person;
    @ResponseBody
    @RequestMapping("/test2")
    public String test2(){
        System.out.println(person); //输出Person{name='zhangshan', age=20}
        return "通过注解@ConfigurationProperties(prefix = 'xxxx')的方式来获取配置文件中的值";
    }
}

在@ConfigurationProperties这一种方式中,和在Spring中获取请求参数的值方式类似。只是这里是要求配置文件中的名字要和对应的类成员名字相同,而获取请求参数的值中,则是需要参数的名字和类成员名字相同,才会将请求参数的数据封装到一个类中。可以参考这一个文章:Spring学习_day4~5

Spring Boot中的profile配置文件

profile配置文件主要是用于不同的环境中,动态进行配置的,例如在生产,开发或者测试的环境下,为了避免重复进行配置环境,这时候就需要profiles动态设置在什么环境下需要使用的是哪一个配置文件。

例如下面所示,我们创建以下profiles配置文件:

application-dev.properties:(格式为application-{profiles}.properties)

server.port=8081

application-pro.properties:

server.port=8089

application-test.properties:

server.port=8989

这时候我们还没有激活profile,也即还没有设置环境,那么这时候就会默认使用的是application.properties中设置的端口8080,并且提示没有设置环境。
在这里插入图片描述

但是一旦我们在applicaton.properties中设置了要激活哪一个profile配置文件的时候,那么端口号就变成了对应的文件中设置的值了。例如我们在application.properties中添加这一行spring.profiles.active=dev,表示我们要激活的是application-dev.properties配置文件,这时候再次运行时,就提示了激活的是dev的profile配置文件。

同样的,我们也可以在创建的是application-dev.yml作为profile配置文件,然后再执行spring.profiles.active=dev来激活这个profile配置文件。

但是这时候可以看到我们创建了许多个配置文件,这时候我们可以用一个yml文件来囊括这多个配置文件,这时候我们就只需要创建一个yml文件,就可以实现创建多个profile配置文件了。这时候我们只需要再yml文件中利用---来进行分隔不同的profile配置文件即可。application.yml代码如下所示:

---
server:
  port: 8081

spring:
  profiles: dev # 表示这中间的配置是属于dev环境的
---
server:
  port: 8082
spring:
  profiles: pro # 表示这中间的配置是属于pro环境的
---
server:
  port: 8083
spring:
  profiles: test # # 表示这中间的配置是属于test环境的
---

然后再配置文件application.properties中执行spring.profiles.active来激活哪一个profile环境即可。

但是这样还是要通过修改配置文件来激活profile环境,那么我们是否有不修改配置文件的方式来激活呢?当然是有的,我们可以通过下面的样子来进行配置:
在这里插入图片描述

点击Edit Configurations,然后选中点击,之后就可以看到下图所示:
在这里插入图片描述

如果左边没有看到Spring Boot这个选项,那么我们需要点击上面的+,然后找到Spring Boot即可。这时候我们可以看到右边的Environment下面有VM options以及Program arguments。这时候我们只要修改这2个中的一个,都可以实现激活profile。

其中VM options是通过JVM来激活的,对应的格式为-Dspring.profiles.active=xxx(不要忘记前面有-D),表示需要激活xxx的profile环境。而Program arguments的值则是--spring.profiles.active=xxx(不要忘记前面有--)

当然我们也可以生成这个项目的jar包之后,再输入命令行来配置环境,如下所示:
在这里插入图片描述

点击了Maven -> 找到对应Module -> 点击Lifecycle -> 点击package,然后就会再控制台中输出一系列的信息,我们重点看生成的对应jar包的位置即可。
在这里插入图片描述

然后再命令行的窗口中输出要运行对应的jar包,然后再输入--spring.profiles.active=xxx来激活对应的profiles配置文件。如下所示:
在这里插入图片描述

Spring Boot内部配置文件的加载顺序

首先先说一下再Spring Boot内部中配置文件的加载顺序为:

  1. 项目目录下面的config包下的配置文件
  2. 项目目录下面的配置文件
  3. classpath下面的config包下的配置文件,也即resources包下的config包下的配置文件
  4. classpath下的配置文件,也即resources包下的配置文件

如图所示:
在这里插入图片描述

加载配置文件的信息,顺序如下所示,如果没有办法找到项目设置项目目录下面创建配置文件,也就是前2个配置文件,需要点击Project -> Project File即可,然后就可以开始创建对应的配置文件了

而对于外部jar包配置文件的加载顺序,则可以参考官网上面,但是主要的顺序是

  1. 命令行进行设置配置文件的信息,或者通过--spring.config.locaton=xxx来指定要读取对应路径下面的配置文件
  2. 这个maven导出的jar包外面的配置文件,而在这些外部配置文件中,同样遵循先加载config包下面的配置文件,然后再加载这个目录下面的配置文件。
  3. 这个maven对应的jar包内部的配置文件。
    在这里插入图片描述
    这样的话,当我们运行这个jar包的时候,就会根据上面的顺序进行加载配置文件,但是如果是在IDEA中运行项目的时候,那么它是根据这个jar包内部的配置文件进行加载的

Spring Boot整合junit,mybatis以及redis

Spring Boot整合 junit

当我们创建好项目之后,这时候来到pom.xml文件,可以看到已经导入了test依赖,即如下所示:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

这时候我们就可以在test包下进行测试了。其中需要测试的步骤是:

  • 在类的上方使用注解@SpringBootTest(classes = 启动类.class),如果是在test包下面的项目名这个包下面,那么就不需要这个注解可以不需要设置classes属性的值
  • 利用@Autowired导入需要测试的bean对象进行测试

Spring Boot整合mybatis

Spring Boot整合mybatis的基本步骤:

  • 导入依赖,比如我们需要利用mybatis进行测试,所以需要导入数据库的联结对象以及mybatis-spring依赖,如下所示:

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    
    <!--数据库-->
    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    
  • 配置数据源信息,只需要在application.properties或者创建application.yml,然后再配置文件中进行设置driver,url,username,password等信息即可。

  • 配置mybatis的核心配置文件,同样是可以再application.properties或者application.yml中进行设置的,从而可以设置mybatis的核心配置文件的路径,映射文件的路径或者别名等属性。

    # 配置数据库的基本信息
    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db1?serverTimezone=Asia/Shanghai
        username: root
        password: root
    # 配置mybatis
    mybatis:
      mapper-locations: classpath:mappers/*Mapper.xml # 配置映射文件的路径
      # 配置别名,相当于<package location="xxx">,这样对应的别名就是对应的类名的缩写形式
      type-aliases-package: com/example/springboot_redis/domain
      # config-location:  配置mybatis的核心配置文件的路径
    
  • 创建实体类User,对应代码:

    public class User {
        private int id;
        private String name;
        private String password;
        private String email;
        private String phone;
    
        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;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getEmail() {
            return email;
        }
    
        public void setEmail(String email) {
            this.email = email;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", password='" + password + '\'' +
                    ", email='" + email + '\'' +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    }
    
    
  • 创建对应的Mapper接口。这时候我们可以利用注解开发来操作mybatis,也可以通过xml来操作。如果我们是通过xml来操作mybatis,那么这时候我们通过利用代理来实现dao层的操作,并且需要创建对应的映射文件,需要在配置mybatis的时候,需要设置映射文件的路径,对应的代码为:

    @Repository //可有可无的,只是在利用@Autowired注入的时候,IEDA中对应的变量下面显示红色的波浪线
    @Mapper //这个注解是必须的,否则就会发生报错,这个作用相当于在SSM整合的过程中需要注入mapper的作用一样的,将扫描这个类,然后自动创建它的动态代理类,注入到spring容器中
    public interface UserXmlMapper {
        List<User> findAll();
    }
    
    

    对应的映射文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.springboot_redis.mapper.UserXmlMapper">
    
        <select id="findAll" resultType="user">
           select * from user
        </select>
    </mapper>
    

    如果是利用注解进行开发的话,那么这时候不需要创建对应映射文件,只是需要在Mapper接口中,对应的方法上面利用对应的注解,表示对应的操作,对应的代码为:

    @Repository //可有可无
    @Mapper //生成对应的mapper接口的动态代理对象,注入到spring容器中
    public interface UserMapper {
        @Select("select * from user")
        List<User> findAll();
    }
    

    整合junit进行测试的代码为:

    @SpringBootTest(classes = SpringbootRedisApplication.class)
    public class MybatisTest {
        @Autowired
        private UserXmlMapper userXmlMapper; //用xml来操作mybatis
    
        @Test
        public void test(){
            List<User> userList = userXmlMapper.findAll();
            for(User user : userList){
                System.out.println(user);
            }
        }
    
        @Autowired
        private UserMapper userMapper; //用注解开发来操作mybatis
        @Test 
        public void test2(){
            List<User> userList = userMapper.findAll();
            for(User user : userList){
                System.out.println(user);
            }
        }
    }
    
    

    值得注意的是,注解@SpringBootTest的属性classess的值是否省略,是看它的位置的。如下所示:
    在这里插入图片描述

Spring Boot整合redis

Spring Boot整合redis的基本步骤为:

  • 导入spring-boot-starter-data-redis依赖
  • 配置redis的信息,例如默认情况下它的端口时6379,host默认是本地主机等
  • 进行测试,但是前提是我们windows中已经安装了redis,对于安装redis的过程,请参考这篇文章:Redis安装(Windows环境下Redis安装)

测试类对应的代码为:

@SpringBootTest(classes = SpringbootRedisApplication.class)
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void setTest(){
        redisTemplate.boundValueOps("name").set("zhangshan");
    }

    @Test
    public void getTest(){
        Object name = redisTemplate.boundValueOps("name").get();
        System.out.println(name);
    }
}

先在命令行窗口中运行了redis,然后再运行setTest方法,之后在运行getTest,这时候就会再控制台中打印出name对应的值zhangshan.

安装redis的过程,请参考这篇文章:Redis安装(Windows环境下Redis安装)

测试类对应的代码为:

@SpringBootTest(classes = SpringbootRedisApplication.class)
public class RedisTest {
    @Autowired
    private RedisTemplate redisTemplate;

    @Test
    public void setTest(){
        redisTemplate.boundValueOps("name").set("zhangshan");
    }

    @Test
    public void getTest(){
        Object name = redisTemplate.boundValueOps("name").get();
        System.out.println(name);
    }
}

先在命令行窗口中运行了redis,然后再运行setTest方法,之后在运行getTest,这时候就会再控制台中打印出name对应的值zhangshan.

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值