还不会springboot?五分钟教会你

107 阅读9分钟

SpringBoot

1 SpringBoot简介

SpringBoot特点

  • SpringBoot Starter:SpringBoot将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的MavenGradle构建中,并且通过这种方式解决了由于版本冲突带来的各种问题,如原本我们要使用一个框架必须找到其前置依赖的版本,并且还要避免和其他包产生冲突,如今我们只需要在依赖Spring-boot-starter-parent的基础上直接引入其他Starter即可。
  • 自动配置:SpringBoot采用约定大于配置的思想,极大程度简化了配置,只需要一个配置文件就能完成所有配置,并且大量采用默认配置,使得SpringBoot项目只需要少量配置就可以运行
  • 内置Servlet Container:SpringBootspring-boot-starter-web内置了tomcat,不需要配置web.xml,也不需要配置tomcat容器,只需要通过main方法就可以部署并运行,同理只需要更换starter就可以更换其他内置Servlet容器

2 SpringBoot快速入门

接下来我们通过一个快速入门案例搭建一个基于SpringBootweb工程

2.1 创建maven工程并导入起步依赖

<!--父工程-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.7.RELEASE</version>
</parent>

<!--依赖-->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2.2 配置入口

SpringBootDemo1App

此处的main方法是发布springboot应用的入口

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@SpringBootApplication
public class SpringBootDemo1App {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemo1App.class,args);
    }
}

代码说明:

1:通过运行main方法,就可以发布一个springboot应用
2:SpringApplication.run相当于之前将web工程发布到tomcat服务器,只是在springboot中集成了tomcat插件
3:@SpringBootApplication表示当前类是一个SpringBoot应用启动类,后面会详细讲解该注解

2.3 编写Controller

HelloController

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@RestController
public class HelloController {

    @GetMapping(value = "/hello")
    public String hello(){
        return "hello springboot!";
    }
}

2.4 测试

运行SpringBootDemo1App的mian方法,可以看到以下内容:

image-20220220174340599

访问http://localhost:8080/hello,可以看到以下内容:

image-20220220174503882

如此简单就启动了一个web项目对比之前繁琐的SpringMVC开发过程,能否感受到SpringBoot的魅力呢。

3 SpringBoot启动原理

通过第2节的入门案例,我们非常容易就完成了一个web项目的配置并通过入口启动,那么这个过程究竟发生了什么,SpringBoot又是如何做到这一点的,带着这个问题接下来我们对SpringBoot的运行原理进行分析。

3.1 为你操碎心的spring-boot-starter-parent

我们可以打开pom.xml中的parent,并查看spring-boot-starter-parent信息。

image-20220220175329433

image-20220220175629203

image-20220220180639254

可以看到这里配置管理了大量的版本,这些版本都是绑定了spring-boot-starter-parent对应的版本(此处为2.3.7.release),也就意味着当你选择了一个版本的spring-boot-starter-parent也就选择了该parent对应的所有依赖版本,并且通过Starter进行分组管理所需的版本,我们将窗口下拉可以看到

image-20220220181003740

这里同时管理了各种可能用到的Starter的版本,回到项目本身的pom文件我们点击进入spring-boot-starter-web,可以看到

image-20220220181329427

这里配置了一个web项目所需的依赖,通过查看以上pom依赖,想必你此刻能够理解SpirngBoot为了解决包冲突以及能够让你使用简单的依赖就可以配置完成一个web项目所有的依赖做所的努力。

3.2 自动配置类

当然spring-boot-starter-parent只解决了依赖问题,对于一个web项目所需的配置还需要别的处理,

3.2.1 @SpringBootApplication

在我们的启动类上面有@SpringBootApplication注解,该注解是一个组合注解,包括如下注解,其中重要的三个注解由红框标出

image-20220220182057628

  • @SpringBootConfiguration:就是一个@Configuration注解,声明为一个配置类
  • @ComponentScan:Spring IOC容器的扫描包,默认扫描引导程序下的包以及子包,如果我们写的程序不在该包范围内,可以通过该注解指定。
  • @EnableAutoConfiguration:Springboot实现自动化配置的核心注解。

3.2.2 @SpringBootConfiguration

image-20220220182312093

通过这段我们可以看出,在这个注解上面,又有一个@Configuration注解。通过上面的注释阅读我们知道:这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了@Configuration的类,并且读取其中的配置信息。而@SpringBootConfiguration是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。

3.2.3 @EnableAutoConfiguration

@EnableAutoConfiguration告诉Spring Boot基于你所添加的依赖,去“猜测”你想要如何配置Spring。比如我们引入了spring-boot-starter-web,而这个启动器中帮我们添加了tomcatSpringMVC的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了webSpringMVC的默认配置了!

自动配置:SpringBoot所有配置都存在默认值,你可以0配置启动项目,也可以主动配置修改默认配置,从而启动项目。

image-20220220182517174

该配置文件使得端口默认为8080

4 SpringBoot配置文件

我们知道SpringBoot是基于约定的,所以很多配置都有默认值。如果想修改默认配置,可以使用application.propertiesapplication.yml(application.yaml)自定义配置。SpringBoot默认从Resource目录加载自定义配置文件。application.properties是键值对类型(一直在用,而且默认生成)。application.ymlSpringBoot中一种新的配置文件方式。

4.1 application.properties

4.1.1 说明

1:如果是修改SpringBoot中的默认配置,那么key则不能任意编写,必须参考SpringBoot官方文档。
2:application.properties官方文档https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle

4.1.2 案例

application.properties

resources目录下新建application.properties

#服务端口
server.port=8081
#项目根路径
server.servlet.context-path=/test

4.1.3 测试

此时运行,tomcat端口发生了变化。

image-20220220183239934

通过/test路径访问/hello接口

image-20220220183341019

4.2 application.yml

4.2.1 语法说明

普通数据:

说明:
key: value(注意:冒号有一个空格)

示例:
name: tom

对象数据或map

说明:
key:
	key1: value1
	key2: value2
	
示例:
user:
	name: tom
	age: 23
	addr: beijing

集合数据1:存储简单类型

说明:
key:
	value1
	value2
或:
key: value1,value2

示例:
city:
	beijing
	anhui
	jiangxi
	shenzhen
或:
city: beijing,anhui,jiangxi,shenzhen

集合数据2:存储对象类型

说明:
key:
	key1: vlaue1
	key2: value2
	
示例:
student:
	- name: zhangsan
	  age: 23
	  addr: BJ
	- name: lisi
	  age: 25
	  addr: SZ
	

4.2.2 案例

将demo中的application.properties换成application.yml,代码如下:

server:
  port: 8081
  servlet:
    context-path: /test

4.2.3 测试

此时运行,tomcat端口发生了变化。

image-20220220183829098

通过/test路径访问/hello接口

image-20220220183341019

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

4.3.1 使用注解@Value映射

@value注解将配置文件的值注入到Spring管理的Bean属性值

4.3.1.1 案例

引入lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

application.yml

server:
  port: 8081
  servlet:
    context-path: /test
usera:
  name: zs
  age: 15

UserConfigValue

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@Configuration
public class UserConfigValue {

    @Value("${usera.name}")
    private String name;

    @Value("${usera.age}")
    private Integer age;

    @PostConstruct
    public void init(){
        System.out.println("name:"+name+"|age:"+age);
    }
}

4.3.2.2 测试

启动项目,可以看到打印如下信息

image-20220220185456690

4.3.2 使用注解@ConfigurationProperties映射

通过注解@ConfigurationProperties(prefix=''配置文件中的key的前缀")可以将配置文件中的配置自动与实体进行映射。

使用@ConfigurationProperties方式必须提供Setter方法,使用@Value注解不需要Setter方法。

4.3.2.1 案例演示

引入lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

application.yml

server:
  port: 8081
  servlet:
    context-path: /test
usera:
  name: zs
  age: 15

UserConfig

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@Configuration
@ConfigurationProperties(prefix = "usera")
public class UserConfig {

    @Setter
    private String name;

    @Setter
    private Integer age;

    @PostConstruct
    public void init(){
        System.out.println("name:"+name+"|age:"+age);
    }
}

4.3.2.2 测试

启动项目,可以看到打印如下信息

image-20220220185456690

5 SpringBoot与其他框架集成

5.1 集成mybatis-plus

集成步骤:

1:搭建springboot工程
2:引入springboot相关依赖包
3:编写pojo
4:创建Dao接口以及Dao映射文件
5:编写Controller调用Dao
6:编写配置文件,配置数据源地址和Tomcat端口
7:编写SpringBoot引导类
8:发布测试

5.1.1 数据准备

建表sql

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`address` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '北京');
INSERT INTO `user` VALUES ('2', 'lisi', '123', '上海');

5.1.2 创建工程

spring_boot_mybatis_demo的pom.xml依赖如下:

 <!--依赖-->
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.1</version>
    </dependency>
</dependencies>

5.1.3 代码实现

User

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@Data
@TableName
public class User implements Serializable {

    @TableId
    private Integer id;
    private String username;
    private String password;
    private String address;
}

UserDao

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
public interface UserDao extends BaseMapper<User> {
}

UserController

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    UserDao userDao;

    @GetMapping
    public Object hello(){
        return userDao.selectList(null);
    }
}

SpringBootDemo2App

/**
 * Copyright (c) 2022 itmentu.com, All rights reserved.
 *
 * @Author: yang
 */
@SpringBootApplication
@MapperScan("com.itmentu.dao")
public class SpringBootDemo2App {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemo2App.class,args);
    }
}

application.yaml

server:
  port: 8082
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
    map-underscore-to-camel-case: true
    # 该配置就是将带有下划线的表字段映射为驼峰格式的实体类属性
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3307/itmentu?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
    username: root
    password: 123456

5.1.4 测试

image-20220220195352233

5.2 集成Spring Data Redis

Spring Data:  Spring 的一个子项目。用于简化数据库访问,支持NoSQL关系数据库存储。其主要目标是使数据库的访问变得方便快捷。

5.2.1 添加Redis启动器

这里我们就不在单独创建工程了,就直接在5.1节中添加Redis启动器。

<!--redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

5.2.2 配置application

在application.properties文件中配置连接Redis的信息:

#redis,端口可以不填,默认就是6379
spring.redis.host=192.168.211.132
spring.redis.port=6379

5.2.3 更新程序

更新UserServiceImpl类中的findAll方法。在该类中注入RedisTemplate对象。

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 查询所有
     * @return
     */
    @Override
    public List<User> findAll() {
        String key = "UserList";
        //先看缓存中是否有数据
        List<User> users = (List<User>) redisTemplate.boundValueOps(key).get();

        //如果有,直接取缓存数据
        if(users!=null){
            return users;
        }

        //如果没有,则查询数据
        users = userMapper.findAll();

        //再将数据存入到缓存
        redisTemplate.boundValueOps(key).set(users);
        return  users;
    }
}

5.1.4 测试

请求<http://localhost:8080/user/findAll> 如果发生如下异常,说明javabean没有序列化,修改User对象,实现Serializable即可。

1563013256647