狂神说springboot(纯应用部分)

狂神说springboot


1.说在前面

javase: oop

mysql: 持久化

html+css+js+jquery+框架: 视图

javaweb: 独立开发mvc三层架构的网站(原始版)

ssm: 框架,简化我们的开发流程,但是随着发展,配置开始较为复杂

在这之前,程序都是打包成war包,在tomcat上运行,从springboot开始打包成jar包(内嵌tomcat来运行)

spring再简化: springboot横空出世,微服务架构

服务增多:springcloud来管理微服务


1.1 优点

  • 为所有spring开发者更快入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化web项目
  • 没有冗余代码生成和xml配置要求

1.2 什么是微服务?

微服务是一种架构风格,他要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合:可以通过http的方式进行互通.

单体应用架构

(all in one) 将一个应用的中的所有内容封装到一个应用中.放到一个war包内.

  • 这样做的好处是,易于开发和测试,部署也十分方便,需要拓展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以了
  • 缺点是,哪怕修改了很小的一个地方,我们都需要停掉整个服务,重新打包,部署这个应用的war包.特别是对于一个大型项目.我们不可能把所有的内容放到一个war里面,我们如何维护和分工都是问题…

微服务架构

所谓微服务架构就是打破all in one的模式,把每个功能元素单独拿出来.把独立的功能元素动态组合,需要的功能才去拿来组合,需要多一些的功能时整合多个功能元素,所以微服务架构就是对功能元素进行复制,而没有对整个应用进行复制.

好处

  • 节省资源
  • 每个功能元素都是可替换的,可独立升级的软件代码

2.第一个springboot程序

环境

  • jdk 1.8
  • maven 3.6.3
  • springboot
  • idea 2021.1.1

官方:提供了一个快速生成的网站

  • 可以再官网直接下载后导入idea开发 https://start.spring.io/
  • 直接使用idea创建一个springboot项目(一般直接在idea中创建)

在idea中直接生成

在这里插入图片描述

选择springweb

在这里插入图片描述


这个时候可能会遇到war包下载失败的问题

** 解决方案: **https://blog.csdn.net/weixin_36827459/article/details/108317079?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-1.no_search_link&spm=1001.2101.3001.4242

https://blog.csdn.net/weixin_41450959/article/details/106109392

如果还是无法解决,就调低springboot的版本继续尝试.通常问题可以得到解决


建包时的注意点

在这里插入图片描述

新建的包要和application类同一级否则无法识别到

package com.example.demo.controller;

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

@Controller
public class HelloController {
    
    

    // http://localhost:8080/hello
    @ResponseBody
    @RequestMapping("/hello")
    public String test01(){
    
    
        return "hello,world!";
    }
}

结果

在这里插入图片描述


修改端口号

在resources文件夹下application.properties中==# server.port=8081 修改端口号==

2.1 小彩蛋


修改springboot启动页面的图标

**网站:**https://bootschool.net/ascii

在resource下新建banner.txt文件夹

在这里插入图片描述

效果
在这里插入图片描述



3.sprinboot自动装配原理(待补充)

自动配置

pom.xml

  • spring-boot-dependencies : 核心依赖在父工程中
  • 我们在写或者引入sprinboot依赖的时候,不需要指定版本,因为有这些版本仓库

启动器

  • <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
  • 启动器就是springboot的启动场景

  • 比如spring-boot-starter-web,他就会帮我们自动导入web依赖的环境

  • springboot会将所有的功能场景,都变成一个个启动器

  • 我们要使用什么功能,就只需要找到一个个启动器就可以了


主程序

package com.example.demo;

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


/*
* 本身就是spring的一个组件
* */

@SpringBootApplication
public class Demo2Application {
    
    

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

}

注解

@SpringBootConfiguration   springboot配置
    @Configuration         spring配置类
    	@Component         spring组件
    
    
@EnableAutoConfiguration        自动配置
    @AutoConfigurationPackage   自动配置包
    	@Import({
    
    Registrar.class})  导入了选择器
    


4.springboot配置

springboot的配置文件application.properties到底可以配置一些什么呢?

springboot使用一个全局的配置文件,配置文件名称是固定的

  • application.properties
    • 语法: key=value
  • application.yml
    • 语法: key:(空格)value

4.1 yaml

YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。

标记语言

以前的配置文件大多使用xml来配置,但是xml配置起来不如yaml轻巧

# k: v
name: kuquan

# object
student:
  name: kuquan
  age: 3

# object inline
stuent: {
    
    name: kuquan, age: 3}

# array
petsArr1:
  -dog
  -cat
  
# array inline
petsArr2: [cat, pig, dog]

properties只能存键值对

yml的值可以注入到我们的配置类中



4.2 给属性赋值的几种方法

4.2.1 yaml赋值

注入

在这里插入图片描述


不影响运行

在这里插入图片描述


==@ConfigurationProperties(prefix = “person”)==和配置文件中的属性绑定


结果

在这里插入图片描述

如果想避免爆红

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

4.2.2 properties配置

通过properties来配置

在这里插入图片描述


对比

在这里插入图片描述

  • spEL:springbootEL表达式
  • 松散绑定:yaml中的last-name可以和类中的lastName绑定,也就是-后面的字母默认大写的,这就是松散绑定.
  • JSR303数据校验:我们可以在字段上增加一层过滤器验证,可以保证数据的合法性.

结论

  • 配置yml和配置properties都可以获取到值,强烈推荐yml
  • 如果我们在某个业务中,只需要获取文件中的某个值,可以使用@value
  • 如果说,我们专门编写了一个javaBean来和配置文件进行映射,就直接使用@ConfigurationProperties(prefix = “xxx”)


4.3 JSR303校验

@Validated 数据校验

类上加完数据校验的注解之后,之后的成员变量上可以加注解

在这里插入图片描述



在这里插入图片描述



4.4 多环境配置及配置文件位置

4.4.1 yaml多文件模块

springboot的多环境配置,选择选择激活哪一个配置文件

spring.profiles.active=(跟application-后面的那个值)

yaml多文件模块

# 选择激活的模块
spring:
  profiles:
    active: dev

---

server:
  port: 8081

# 配置环境名称
spring:
  profiles: dev


---
server:
  port: 8082

相当于配置了三个文件



4.4.2 springboot配置文件加载优先级

  • 优先级1:项目路径下config文件夹下配置文件
  • 优先级2:项目路径下配置文件
  • 优先级3:资源路径下config文件夹配置文件
  • 优先级4:资源路径下配置文件


4.4.3 配置项目访问路径

# 配置项目的访问路径(默认是/)
server:
  servlet:
    context-path: /edu


4.5 自动装配再理解(待补充)

查看哪些自动配置类生效了

debug: true


5.springboot WEB开发

要解决的问题:

  • 导入静态资源
  • 首页
  • jsp,模板引擎thymleaf
  • 装配扩展springmvc
  • 视图解析器
  • 增删改查
  • 拦截器
  • 国际化


5.1 静态资源问题

在这里插入图片描述

静态资源就放置在这里


静态资源导入的源码

public void addResourceHandlers(ResourceHandlerRegistry registry) {
    
    
    if (!this.resourceProperties.isAddMappings()) {
    
    
        logger.debug("Default resource handling disabled");
    } else {
    
    
        this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
        this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
    
    
            registration.addResourceLocations(this.resourceProperties.getStaticLocations());
            if (this.servletContext != null) {
    
    
                ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                registration.addResourceLocations(new Resource[]{
    
    resource});
            }

        });
    }
}

5.1.1 webjars是什么?

在这里插入图片描述

可以以maven的方式引入前端资源


在这里插入图片描述


*访问资源->http://localhost:8080/webjs/ **

在这里插入图片描述



5.1.2 静态资源的放置路径(优先级)

  • classpath:/META-INF/resources
  • classpath:/resources/ 1
  • classpath:/static/ 2
  • classpath:/public/ 3


5.2 首页

放置位置

在这里插入图片描述

在这三个文件中的中的一个放置一个名为index.html的文件就会被扫描出来作为首页



5.3 模板引擎Thymeleaf

简介

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。

官网 Thymeleaf


maven依赖

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
</dependency>

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-java8time</artifactId>
</dependency>

springboot自带的thymeleaf太老了.不合适了,现在都是基于3.x版本开发

**结论:**只要需要使用thymeleaf,只需要导入对应的依赖就可以了!我们将html放在我们的templates文件夹下即可

5.3.1 thymeleaf使用

  • 第一步,导入约束在html中
<html xmlns:th="http://www.thymeleaf.org">

5.3.2 第一个Thymeleaf

  • controller
 @RequestMapping("/test")
public String index(Model model){
    
    
    model.addAttribute("msg", "hello springboot");
    return "test";
}
  • view
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--所有的html元素都可以被thymeleaf接管,直接属性中添加th:xx即可-->
  <h1 th:text="${msg}"></h1>
</body>
</html>
  • 结果

在这里插入图片描述




5.3.3 thymeleaf基本语法

Thymeleaf 基本用法总结 - micrsoft - 博客园 (cnblogs.com)



5.4 mvc配置原理(之后补充)



5.5 springmvc配置(部分)

  • 一个配置模板
package com.example.springboot03web.config;

/*
* 全面扩展springmvc
* @Configuration:变成一个配置类
* */

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
    
    
    /*
    * 配置
    * */
}

springboot中,有很多的xxx @Configuration,帮助我们进行拓展配置,只要看见这个东西,我们就要注意了,看看它帮我们配置了什么东西.



6.Data


6.1 回顾jdbc

  • 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
  • 配置数据库链接
spring:
  datasource:
    username: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    password: 123
  • 测试数据源and数据库连接
package com.example.springboot04data;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@SpringBootTest
class Springboot04DataApplicationTests {
    
    

    @Autowired
    private DataSource dataSource;

    @Test
    void contextLoads() throws SQLException {
    
    
        /*
        * 查看默认数据源
        * */
        System.out.println(dataSource.getClass());

        /*
        * 数据库连接
        * */
        Connection connection = dataSource.getConnection();
        System.out.println(connection);

        // xxx.template : springboot已经配置好的bean


        connection.close();
    }

}

  • 结果

在这里插入图片描述

默认的数据源是springboot内置的hikari

  • 测试数据库连接
package com.example.springboot04data.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class JDBCController {
    
    

    @Autowired
    private JdbcTemplate jdbcTemplate;


    /*
    * 没有实体类数据库中的东西可以用map来获取
    * */
    @GetMapping("/alluser")
    public List<Map<String, Object>> test01() {
    
    
        String sql = "select * from user";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
        return list;
    }
}


结果

在这里插入图片描述



**结语:**springboot帮我们整合了jdbc,现在jdbc操作起来也十分的简单



6.2 整合Druid

  • 依赖(因为配置druid的时候使用了log4j,所以一并导入)
<!-- druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.21</version>
</dependency>

<!--log4j-->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
  • 配置application
spring:
  datasource:
    username: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
    password: 123
    type: com.alibaba.druid.pool.DruidDataSource
    # druid 专有配置
    initial-size: 5
    min-idle: 5
    max-active: 20
    max-wait: 60000
    time-between-eviction-runs-millis: 60000
    min-evictable-idle-time-millis: 300000
    validation-query: SELECT 1 FROM DUAL
    test-while-idle: true
    test-on-borrow: false
    test-on-return: false
    pool-prepared-statements: true
    # 配置监控拦截的filters.stat:监控统计,log4j:日志记录,wall:防止sql注入
    filters: stat,wall,log4j
    max-pool-prepared-statement-per-connection-size: 20
    use-global-data-source-stat: true
    connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    # 在druid控制界面查看sql语句
    filter:
      stat:
        enabled: true
      wall:
        config:
          multi-statement-allow: true



  • 配置config
package com.example.springboot04data.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {
    
    


    /*
    * yaml中的配置绑定进来
    * */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource() {
    
    
        return new DruidDataSource();
    }

    /*
    * 后台监控  类似于web.xml
    * 因为springboot内置了servlet,所以没有web.xml,代替方法ServletRegistrationBean
    * */
    @Bean
    public ServletRegistrationBean statViewServlet() {
    
    
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");

        /*
        * 配置账号密码
        * */
        HashMap<String, String> initParameters = new HashMap<>();

        /*
        * 配置
        * 配置的key是固定的
        * */
        // 登录账号密码
        initParameters.put("loginUsername", "admin");
        initParameters.put("loginPassword", "123");
        // 允许谁能访问   ""表示都可以访问
        initParameters.put("allow", "");
        // 禁止谁能访问
        initParameters.put("deny", "");


        bean.setInitParameters(initParameters);

        return bean;
    }

    /*
    * filter
    * */
    @Bean
    public FilterRegistrationBean webStatFilter() {
    
    
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<>();

        bean.setFilter(new WebStatFilter());

        // 过滤哪些请求
        Map<String, String> initParameters = new HashMap<>();

        bean.addUrlPatterns("/*");
//        bean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

        initParameters.put("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");

        bean.setInitParameters(initParameters);

        return bean;
    }
}

  • 测试

在这里插入图片描述


在这里插入图片描述


在这里插入图片描述



6.3 整合Mybatis

  • 依赖
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.3</version>
</dependency>
  • 配置
spring:
  datasource:
    username: root
    password: 123
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8


# 整合mybatis
mybatis:
  type-aliases-package: edu.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml
  • 编写pojo类
package edu.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.type.Alias;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Alias("user")
public class User implements Serializable {
    
    
    private int id;
    private String name;
    private String pwd;
}
  • 编写mapper
package edu.mapper;

import edu.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/*
* @Mapper
* 表示这是一个mybatis的mapper类
* */

@Mapper
@Repository
public interface UserMapper {
    
    

    List<User> queryAllUser();

    User queryUserById(@Param("id") int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(@Param("id") int id);
}

  • 编写mapper的配置文件
<?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">

<!--xxx:接口的全路径-->
<mapper namespace="edu.mapper.UserMapper">
    <!--在当前xml中使用二级缓存-->
    <cache></cache>

    <select id="queryAllUser" resultType="list">
        select * from user
    </select>

    <select id="queryUserById" resultType="user">
        select * from user where id=#{id}
    </select>

    <insert id="addUser" parameterType="user">
        insert into user values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="user">
        update user set name=#{name},pwd=#{pwd} where id=#{id}
    </update>

    <delete id="deleteUser">
        delete from user where id=#{id}
    </delete>

</mapper>
  • 编写service
package edu.service;

import edu.mapper.UserMapper;
import edu.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserService {
    
    
    @Autowired
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper) {
    
    
        this.userMapper = userMapper;
    }

    public List<User> queryAllUser() {
    
    
        return userMapper.queryAllUser();
    }

    public User queryUserById(int id) {
    
    
        return userMapper.queryUserById(id);
    }

    public int addUser(User user) {
    
    
        return userMapper.addUser(user);
    }

    public int updateUser(User user) {
    
    
        return userMapper.updateUser(user);
    }

    public int deleteUser(int id) {
    
    
        return userMapper.deleteUser(id);
    }
}

  • 编写controller
package edu.controller;

import edu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class UserController {
    
    

    @Autowired
    private UserService service;

    public void setService(UserService service) {
    
    
        this.service = service;
    }

    @GetMapping("/user/alluser")
    public String queryAllUser() {
    
    
        return service.queryAllUser().toString();
    }
}

  • 结果

在这里插入图片描述



serMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}

public List<User> queryAllUser() {
    return userMapper.queryAllUser();
}

public User queryUserById(int id) {
    return userMapper.queryUserById(id);
}

public int addUser(User user) {
    return userMapper.addUser(user);
}

public int updateUser(User user) {
    return userMapper.updateUser(user);
}

public int deleteUser(int id) {
    return userMapper.deleteUser(id);
}

}


* 编写controller

```java
package edu.controller;

import edu.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class UserController {

    @Autowired
    private UserService service;

    public void setService(UserService service) {
        this.service = service;
    }

    @GetMapping("/user/alluser")
    public String queryAllUser() {
        return service.queryAllUser().toString();
    }
}

  • 结果
    在这里插入图片描述


猜你喜欢

转载自blog.csdn.net/qq_45826803/article/details/120667622
今日推荐