SPRINGBOOT学习记录

SPRINGBOOT

1 入门

1 .1 springBoot具体流程

1yaml 配置文件

2 自动装配

3集成web框架

4 集成数据库

5分布式开发 Dubbo(rpc) zookeeper

6 swagger 接口文档

7 任务调度

8 springSecurity :shiro

1.2 springCould

1 微服务

2 springcould入门

3 RestFul

4 eureka

5 Ribbon

feign

HyStrix

zuul 路由网关

SpringCloud config:git

1.3 什么是微服务

MVC三层 MVVM微服务架构

微服务:是一种架构风格 是一系列小服务的组合 可以通过http互通,把需要的功能调度组合。

2 搭建框架

2.1 idea创建springBoot项目

1直接创建
SPRINGBOOT学习记录

SPRINGBOOT学习记录

2 配置完成后创建controller测试

@RestController
public class Mycontroller {


    @RequestMapping("/hello")
    public String h1(){
        return "我要死了";
    }

}

3 打包成jar包

4 终端调用

java -jar bootpro-0.0.1-SNAPSHOT.jar

5 配置文件 properties

#更改项目端口号
server.port=8081


#自定义banner
spring.banner.location=banner.txt

3 自动装配原理

3.1 自动装配原理

核心的依赖都在父工程中,版本管理和资源过滤

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

我们在引入springboot依赖的时候不需要指定版本,因为父pom中有管理仓库

启动器:

<!--web依赖 tomcat web。xml dispatcherServlet-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

我们需要使用什么功能就引入什么启动器

可以在项目的pom中配置依赖的版本:

<properties>
        <java.version>1.8</java.version>
        <mysql.version>5.*.*</mysql.version>
    </properties>

20210419注:

3.2 主程序

//集成封装了springconfig注解 标注这个类是一个springboot应用
@SpringBootApplication
public class BootproApplication {

    public static void main(String[] args) {
        //通过反射加载类
        SpringApplication.run(BootproApplication.class, args)   }

}

主程序注解

@SpringBootConfiguration //sprng配置文件 就是一个configuration 代表当前类为spring的配置类

@EnableAutoConfiguration //自动装配
//注解扫描
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

//@SpringBoootConfiguration下的注解:(说明该class是一个spring配置类)
@Configuration

//EnableAutoConfigurations下的注解:
@AutoConfigurationPackage //自动配置包
@Import(AutoConfigurationImportSelector.class)//导入选择器

//@AutoConfigurationPackage下的注解
@Import(AutoConfigurationPackages.Registrar.class)//利用registar给容器中批量导入组件


/**
 * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing
 * configuration.
 */
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {

   @Override
   public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
       //将指定的一个包下的所有组件导入进来 默认为主程序所在的包下
      register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
   }

   @Override
   public Set<Object> determineImports(AnnotationMetadata metadata) {
      return Collections.singleton(new PackageImports(metadata));
   }

}

(AutoConfigurationImportSelector.class 给容器导入组件

SPRINGBOOT学习记录

上图 获取所有的候选配置类

每个autoconfiguration(配置类)类 对应一个properties类 通过yaml或properties给具体属性赋值 被调用的autoconfig类会通过@Bean 注解生成程序运行所需的对象交给spring ioc容器管理(生成一个template对象)

SPRINGBOOT学习记录

List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) //这个方法得到所有的组件 从meta-info 下加载文件
    

SPRINGBOOT学习记录

​ 从spring.factories中读取配置(需要加载的类)
SPRINGBOOT学习记录

读取完全部配置 最后按照条件装备规则按需开启 例: 下图类上有注解 当容器中有advice时才加载进容器中 当添加了aop依赖后才能将其加进去
SPRINGBOOT学习记录

主程序运行过程

SpringApplication

1 判断应用的类是普通项目还是web项目

2 加载所有可用的初始化器 设置到initializers中

3 找出所有的应用程序监听器,设置到listener中

5 推断设置main方法的定义类 ,找到运行的主类

注:

springBoot 自动扫描主程序所在的包以及其所有子包下的组件,若想修改则可:@SpringBootApplication(scanBasePackages=“com”)

1 springboot先加载所有的自动配置类

2 每个自动备注类按照条件生效

3 生效的配置类会向容器中注册组件

注解总结:
SPRINGBOOT学习记录

基础注解:

@configuration:

配置类

(proxyBeanMethods=true) 全增量(full)开发模式 严格准守spring约束 bean为单例模式;

= false (lite)不为单例模式 getBean时spring运行时不会做检查 增加效率。

@Configuration
public class MyConfig {

    @Bean("kenan")
    public Student getStudent(){
        return new Student(22,"柯南",1608);
    }
    @Bean("miao")
    public Pet getPet(){
        return  new Pet();
    }
}

@import:

@Import(user.class) 在容器中创建出user类型的组件 默认组件名为全类名(包+类名)

@conditional:

条件装配,满足condition则进行组件注入

@ImportResources:

导入spring配置文件:

@ImportResources(“classpath:**”)

@ConfigurationProperties:

配置绑定

@PropertySource

加载指定的属性文件(*.properties)到 Spring 的 Environment 中。可以配合 @Value 和
@ConfigurationProperties 使用。
@PropertySource 和 @Value
组合使用,可以将自定义属性文件中的属性变量值注入到当前类的使用@Value注解的成员变量中。
@PropertySource 和 @ConfigurationProperties
组合使用,可以将属性文件与一个Java类绑定,将属性文件中的变量值注入到该Java类的成员变量中


1 导入依赖:

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

2 类上加注解:

@ConfigurationProperties(prefix = "mypet")
public class Pet {
    private String species;
    private String name;
}

3 properties文件:

mypet.species="猫"
mypet.name="咪咪"

使用方式:

1: @Component + @ConfigurationProperties

2 @ConfigutationProperties +EnableConfigurationProperties

@EnableConfigurationProperties(HelloServiceProperties.class)

4 yaml

4.1 yaml语法

#yaml格式配置文件
server:
  port: 8081

  #对象
  student:
    name: 克南
    age: 22


    #对象行内写法
  person: {name: 克南, age: 18}


    #数组
  pets:
      - cat
      - dog
      - pig


  #行内写法
  animals: [cat, dog, pig]

4.2 yaml 属性赋值

可以将yaml中的值与bean一一对应,给bean注入值

<!--使用configProperties注解需导入这个依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
@ConfigurationProperties(prefix = "person")
public class Person {

    private String name;
    private int age;
    private Map maps;
}
person:
  name: sama
   age: ${random.int}
  maps: {hobby: girl, like: game}

4.3 指定配置文件

使用指定的properties文件

@PropertySource("classpath:kenan.properties")
name=克南
public class Dog {

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

    private int age;
}

4.4 yaml占位符表达式

id: ${random.int}
id2: ${random.uuid}
say: ${dog.hello:hello}aa #判断式如果冒号前的dog.hello存在 则调用hello的值 否则使用:后面的值

4.5 yaml松散绑定

驼峰和分隔符转换

private String lastName;
person:
    last-name: sama

5 JSR303校验

在后端校验数据的格式

<!--开启后台数据校验-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
@Validated
public class Person {

    @Email(message = "邮箱格式错误")
    private String name;
    private int age;
    private Map maps;
}

default message [邮箱格式错误]; origin class path resource [application.yaml]:3:11

6 多环境配置

配置文件的四个位置

1 根目录下的config文件夹:

2 根目录下:

3 classpath下的config下:

4 classpath下:

优先级 1 》 2 》 3 》4

yaml多环境配置选择 (spring profiles active)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8yQL75kd-1627207396216)(K:\u\study\文档\image-boot原理图6)]
SPRINGBOOT学习记录

server:
    port: 8081
spring:
  profiles:
    active: test
---
server:
  port: 8082
spring:
  profiles: dev


---
server:
  port: 8083
spring:
  profiles: test

7 导入静态资源

WebMvcAutoConfiguration下的

EnableWebMvcConfiguration

public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
    CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
    if (!registry.hasMappingForPattern("/webjars/**")) {
        customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
                                             .addResourceLocations("classpath:/META-INF/resources/webjars/")
                                              .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
    if (!registry.hasMappingForPattern(staticPathPattern)) {
        customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
                                             .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
                                             .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }
}

什么是webjars

springboot使用webjars统一管理静态资源

使用依赖的方式来引入web常用的包库 如jquery 等

SPRINGBOOT学习记录

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.6.0</version>
</dependency>

1 访问静态资源的路径为 /webjars/**

SPRINGBOOT学习记录

2 访问静态资源的默认路径 /** 例如:/t1.txt 那么就会到/** 所对应的映射目录去寻找t1.txt

SPRINGBOOT学习记录

<script src="webjars/jquery/3.4.1/jquery.js"></script>
<--用webjar引用静态资源-->
/**
 * Path pattern used for static resources.
 */
private String staticPathPattern = "/**";
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
      "classpath:/resources/", "classpath:/static/", "classpath:/public/" };

/**
 * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
 * /resources/, /static/, /public/].
 */

一般 static 放图片 public放公共js resources 放上下传文件

三者优先级 r > s > p

3 在配置文件中自定义静态资源位置

spring:
  mvc:
    static-path-pattern: /mystaic/, classpath:/mystatic/

7.1 首页

private Resource getIndexHtml(String location) {
   return this.resourceLoader.getResource(location + "index.html");
}

故须在静态资源文件夹下新建index.html

8 thymeleaf

默认的配置类配置了前缀和后缀

@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

   private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;

   public static final String DEFAULT_PREFIX = "classpath:/templates/";

   public static final String DEFAULT_SUFFIX = ".html";

8.1 开始

可以在yaml中关闭thymeleaf缓存

spirng.thymleaf.cache: false

1导入依赖

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
/*在template文件下的html只能通过controller访问
* 需要模板引擎的支持*/
@Controller
public class IndexController {
    @RequestMapping("/a")
    public String index(){
        return "index";
    }

}

2 导入约束 声明thymeleaf的命名空间

<html lang="en" xmlns:th="http://www.thymeleaf.org">

3 元素中使用th标签

<!--所有的元素都可被html接管-->
<div th:text="${msg}"></div>

8.2 基本语法

<!--所有的元素都可被html接管-->
<div th:text="${msg}"></div>
<!--非转义字符串 可输出html-->
<div th:utext="${msg}"></div>
<!--遍历 users是集合 user是单个元素-->
<h2 th:each="user:${users}" th:text="${user}"></h2>
<!--两个中括号 中间加元素-->
<h2 th:each="user:${users}">
    [[${user}]]
</h2>
//工具类 可以将数组转换为集合
model.addAttribute("users", Arrays.asList("kenan","sama"));
<link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
<link  th:href="@{/css/animate.css}" rel="stylesheet">
<link  th:href="@{/css/style.css}" rel="stylesheet">
<link  th:href="@{/css/login.css}" rel="stylesheet">
<script th:src="@{/js/jquery-3.4.1.min.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>

9 扩展MVC

9.1 扩展MVC

自定义视图解析器

//扩展mvc
@Configuration
public class MyMVC implements WebMvcConfigurer {




    @Bean
public MyViewResolver myViewResolver(){
    return new MyViewResolver();
}


    //自己配置的viewResolver
    class MyViewResolver implements ViewResolver{

        @Override
        public View resolveViewName(String viewName, Locale locale) throws Exception {
            return null;
        }
    }
}
//添加一个视图跳转页面 相当于手动配置controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/user").setViewName("index");
}

9.2 拦截器

@Override
public void addInterceptors(InterceptorRegistry registry) {
    //添加拦截链接 和不拦截的拦截
    registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns();
}

10 整合数据库

10.1 springboot JDBC

1 设置参数

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/graduation_project?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong
    driver-class-name: com.mysql.cj.jdbc.Driver

2 使用spring提供的jdbctemplate操作数据库

@RestController
public class MyController {
    @Autowired
    JdbcTemplate template;
    @RequestMapping("/test")
    public List<Map<String, Object>> t1(){
        String sql = "select * from patients";
        List<Map<String, Object>> maps = template.queryForList(sql);
        return maps;
    }
}
@RequestMapping("update/{name}/{id}")
public String update(@PathVariable("name") String name,  @PathVariable("id") String id){
    String sql = "update patients set p_name = ? where p_id = ?";
    Object[] objects = new Object[2];
    objects[0] = name;
    objects[1] = id;
    template.update(sql,objects);
    return "ok";

}

10.2 整合druid数据源

1 导入maven依赖

com.alibaba druid 1.1.22

2 指定数据库type并配置druid属性

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/graduation_project?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Hongkong
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
#   数据源其他配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
#   配置监控统计拦截的filters,stat监控界面sql统计,'wall'用于防火墙防御sql注入 log4j 日志文件
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500

3 创建druid配置文件使其生效虽然我们配置了druid连接池的其它属性,但是不会生效。因为默认是使用的java.sql.Datasource的类来获取属性的,有些属性datasource没有。如果我们想让配置生效,需要手动创建Druid的配置文件。

 //绑定druiddatasource参数
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource(){
        return new DruidDataSource();
    }
//配置后台监控 注册一个servlet
@Bean
public ServletRegistrationBean tatViewServlet() {
    ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
    //设置后台管理用户 和一些配置
    HashMap<String, String> map = new HashMap<>();
    map.put("loginUsername", "admin");
    map.put("loginPassword", "123456");

    //设置访问白名单
    map.put("allow", "localhost");


    bean.setInitParameters(map);
    return bean;

}

11 整合Mybatis

前情提要:

spring整合mybatis时可以使用MapperScannerConfigurer实现mapper的动态代理(省去了手动实现mapper类的步骤“mapperImpl”)在接口上也可以省去@Repository注解

<!--生成mapper代理类-->
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.zzuli.mapper"/>
</bean>
public interface StuMapper {

    List<Student> getStu();
}

@mapper注解
@mapper在springboot中使用 添加在mapper接口上 在编译后悔生成对应的接口实现类

@MapperScan

在springboot的启动类上添加使用 其所指定的包中的接口在编译后都会生成对应的实现类

11.1 入门

1 引入maven依赖

org.mybatis.spring.boot mybatis-spring-boot-starter 2.1.3

2编写mapper

@Mapper
public interface PatientMapper {
    List<Patient> getPat();

    Patient getPatById(String id);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="zuli.kenan.boot_mybatis.mapper.PatientMapper">


    <select id="getPat" resultMap="patMap">
        select  * from patients
    </select>

    <!--结果集-->
    <resultMap id="patMap" type="zuli.kenan.boot_mybatis.pojo.Patient">
        <result property="id" column="p_id"/>
        <result property="name" column="p_name"/>
        <result property="password" column="password"/>
    </resultMap>
</mapper>
#整合mybatis
mybatis:
  type-aliases-package: zuli.kenan.boot_mybatis.pojo
  mapper-locations: classpath*:mapper/*.xml
@MapperScan("com.kenan.mybatisboot.mapper")

12 SpringSecurity

功能权限

访问权限

菜单权限

需要拦截器 过滤器 都是原生代码

12.1 框架搭建

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //链式调用 建造者模式
        //指定访问策略
        //首页对应的功能页只有对应权限的人才能访问
        //url后面跟参数 * 当参数和hasrole中的规则一致时,才能访问
        http.authorizeRequests().antMatchers("/").permitAll()
                .antMatchers("/level1/**").hasRole("vip1")
                .antMatchers("/level2/**").hasRole("vip2");

        //访问被拦截后会跳到登录面(自带的)he most basic configuration defaults to automatically generating a login page at
        //  * the URL "/login", redirecting to "/login?error" for authentication failure.
        http.formLogin();
    }

    //认证用户  给指定的用户指定相应的role 要设置密码编码不使用明文密码
    // enable in memory based authentication with a user named
    //  *     // &quot;user&quot; and &quot;admin&quot;
    //  *     .inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;).and()
    //  *           .withUser(&quot;admin&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;, &quot;ADMIN&quot;);
    //  * }
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
                .withUser("kenan").password("1234").roles("v1","v2")
                .and()
                .withUser("kenan").password("22").roles("v3");
    }
}

13 Shiro

);

    //访问被拦截后会跳到登录面(自带的)he most basic configuration defaults to automatically generating a login page at
    //  * the URL "/login", redirecting to "/login?error" for authentication failure.
    http.formLogin();
}

//认证用户  给指定的用户指定相应的role 要设置密码编码不使用明文密码
// enable in memory based authentication with a user named
//  *     // &quot;user&quot; and &quot;admin&quot;
//  *     .inMemoryAuthentication().withUser(&quot;user&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;).and()
//  *           .withUser(&quot;admin&quot;).password(&quot;password&quot;).roles(&quot;USER&quot;, &quot;ADMIN&quot;);
//  * }
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth.inMemoryAuthentication().passwordEncoder(new BCryptPasswordEncoder())
            .withUser("kenan").password("1234").roles("v1","v2")
            .and()
            .withUser("kenan").password("22").roles("v3");
}

}


## 13 Shiro

上一篇:求Sn=a+aa+aaa+aaaa+aaaaa的前5项之和,其中a是一个数字


下一篇:铁威马雷电3新品亮相,南京渠道交流会完美落幕