1.springboot简介(背景介绍)

1.1 Spring Boot 概述

现在软件市场已经形成一定的规模,系统架构的复杂度也越来越高(例如有单体架构,分布式架构,微服务架构)。软件的整个架构体系正在发生很大变化,在这种变化中,企业现在更注重技术的开箱即用,更注重技术在生态圈中的深度融合,更注重轻量级的运维。由此spring boot诞生。

说明:学技术一定要了解技术发展史,并对技术的发展有一定的前瞻性。
1.2 Spring Boot 核心特性
Spring boot是一个脚手架(而非框架),构建于Spring框架(Framework)基础之上,基于快速构建理念,提供了自动配置功能,可实现其开箱即用特性(创建完一个基本的项目以后,可零配置或者少量配置即可运行我们的项目),其核心主要有如下几个方面:
起步依赖(Starter Dependency)。
自动配置(Auto Configuration)。
健康检查(Actator)-监控。
嵌入式服务(Tomcat,Jetty).
其中,[springboot官网地址为]https://spring.io/projects/sp...

2.springboot的环境配置

2.1 准备工作
工具下载

  1. 下载JDK1.8,并进行环境变量配置(假如已有则无需再次下载和配置)。
  2. 下载最新maven(例如apache-maven-3.6.3,网址http://maven.apache.org/)并解压。
  3. 下载sts最新版(例如sts-4.4.5.RELEASE,sts网址并解压(新版本下载下来时一个.jar]文件,需要在jar文件所在的目录中,以命令行方式执行java -jar 下载的文件名的方式进行解压,如图-1所示(需要首先启动系统自带的命令行客户端,然后切换到软件所在目录,cd指令为切换目录的意思)。

如图所示

工作区准备:定义新的工作区(要求没有中文目录),例如d:/TCGBIII/CGBWORKSP。

建议:将下载的所有文件存储到同一目录并解压,例如d:/TCGBIII/TCGBTOOLS目录。要求目录不要有中文,也不要有特殊符号(例如&等)。
2.2 Maven基本配置
打开maven中的setting.xml文件,并对其如下选项进行配置。
配置maven本地库(从maven远程服务器下载的资源存储到的位置)

<localRepository>${user.home}/.m3/repository</localRepository>

配置maven私服(远程仓库)(配置到mirrors标签内部)。

<mirror>

 <id>aliyun</id>

 <name>aliyun for maven</name>

 <mirrorOf>\*</mirrorOf>

 <url>https://maven.aliyun.com/repository/public</url>

 </mirror>

配置maven中的profile(配置到profiles标签内部),设置JDK编译和运行版本。

<profile>

 <id>jdk-1.8</id>

 <activation>

 <activeByDefault>true</activeByDefault>

 <jdk>1.8</jdk>

 </activation>

 <properties>

 <maven.compiler.source>1.8</maven.compiler.source>

 <maven.compiler.target>1.8</maven.compiler.target>

  <maven.compiler.compilerVersion>

 1.8

 </maven.compiler.compilerVersion>

 </properties>

</profile>

2.3 STS整合maven配置
step1,启动STS工具,如图所示
step2,Maven Installations配置,
如图所示:
step3, Maven User Settings配置,
如图-所示:
项目工作区编码设为UTF-8,图略

3.springboot的快速入门

3.1 项目创建及结构分析
打开STS 集成开发工具,创建spring boot项目,其具体步骤如下:
第一步:打开项目新建窗口(快捷键ctrl+n), 搜索spring,选择spring starter 项目。
第二步:填写项目基本信息。
如图所示
第三步:选择Spring Boot版本,图略:
在第三步图中点击finish之后,项目便开始从maven配置中指定的私服服务器(例如阿里云的maven服务器)去下载起步依赖(SpringBoot项目中默认指定了项目启动时需要的一些jar包依赖),这个过程可能会比较耗时(网络最好不要用手机网络,会导致很多资源下载不下来),假如指定版本的springboot项目以前创建过,它会默认先从本地库查找,假如本地库没有,则从远程库去下载。
项目创建成功以后,其包视图(Package Explorer)结构。如图-13所示
其中,在图-13呈现的CGB-SBOOT-01项目结构中,所有的类和配置文件都是创建好项目以后,由STS工具帮我们自动创建的。

创建springboot项目的目录结构(即类位置),如图所示

当创建一个maven项目出现了pom.xml文件错误或者项目中红色叉号或叹号怎么办? 可在项目上右键,对项目进行强制maven update。

如何导入一个maven项目(例如通过start.spring.io网页直接生成的项目)?
鼠标右键import,搜索maven,找到已存在的maven project直接引入项目的路径即可。

如何通过start.spring.io网页直接生成一个springboot项目?
如图所示

3.2 项目启动过程分析(了解)
找到项目的入口类(使用了@SpringBootApplication注解描述),然后运行启动类,检测启动过程,SpringBoot在启动时,控制台会出现如图-14标识(图略):

思考:SpringBoot工程在启动时做些什么?
1)通过线程调用相API从指定路径查找相关的配置文件(.class文件)。
2)调用IO对象从磁盘中读取文件(将文件内容读到内存--cpu只能从内存读取数据)。
3)检测类是否有特定的注解描述(例如:@Controller,@Service,@Component ....)
4)Spring框架基于工厂对象(BeanFactory)为指定class创建实例对象,并基于配置描述对这些对象进行初始化操作。
5)将对象存储中Spring框架管理的池中(Bean池--其底层设计在这里是一个map)

项目启动时发生了什么呢?我在这里画了张图帮大家进行一下分析 如图所示:

3.3 项目业务初步实现及测试
业务实现:
基于SpringBoot脚手架,通过Spring框架进行Bean对象的管理实现。
第一步:创建一个DefaultCache类然后交给spring 管理。

package com.cy.pj.common.cache;
/**
 * @Component是Spring中用于描述Bean类的一个注解。用于告诉Spring这个类的实例由Spring创建,
 * 当此对象由Spring创建和管理时,默认会将对象存储到池(Bean池)中。
 */
@Component
public class DefaultCache {}

第二步:添加sringboot 测试类,进行bean的获取及测试,要放在test目录中:

package com.cy.pj.common.cache;

@SpringBootTest//注解用于告诉spring框架,此测试类交给spring管理。这个注解描述的类也会由spring框架进行创建,并且进行值的注入(赋值)

public class DefaultCacheTests {

 @Autowired //@Autowired注解描述的属性,由spring框架进行值的注入(赋值) (至于注入规则,后面会慢慢加强)

 private DefaultCache defaultCache;

 @Test

 public void testCache() {

 System.out.println(defaultCache);

 }

}

第三步:代码设计及运行分析,如图-所示:
在上图中描述了DefaultCacheTests类与DefaultCache类的关系,这两个类通过指定注解(@SpringBootTest,@Component)进行了描述,其意图是告诉spring框架这个两个类的实例的创建由Spring负责,并且由Spring框架基于@Autowired注解的描述完成DefaultCacheTests实例中有关DefaultCache类型的值的注入(DI)。

第四步:为对象设计作用域,设置延迟加载,设置生命周期方法(了解)。

在Spring框架中,Spring为由它创建和管理的对象,设计了一些特性,例如作用域,延迟加载,生命周期方法等,基于这些特性实现对Bean对象的管理。

package com.cy.pj.common.pool;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
/**
 * 假设此对象为一个对象池
 * 1)此对象要交给spring管理(SpringBoot工程下)
 * 1.1)类的位置(必须放在启动类所在包及其子包下)
 * 1.2)类的描述(使用@Component注解)
 * 2)需要此对象的地方可从spring的bean池中获取
 * 思考:
 *  1)如何判定一个对象在何时创建? (通过日志,断点)
 *  2)spring容器中Bean对象默认在启动时创建,但长时间又不使用这个对象,
 *   你觉得先把对象创建出来好吗?(不好,占内存资源,需要才创建,尤其是一些大对象更占内存资源)
 *  3)Spring容器中的Bean对象假如不希望在容器启动时创建,该如何设计呢?  可以延迟加载(按需加载)
 *  
 *  @Lazy注解:描述Spring管理的bena对象时,可以让bean延迟构建及初始化。
 *   延迟加载(又叫按需加载、懒加载)应用场景?
 *    1)大对象(例如一些池对象),稀少用(例如容器初始化创建对象也用不到)。
 *    
 *   @Scope注解描述类时用于指定类实例的作用域,常用取值
 *    1)singleton:默认为单例作用域-类的实例在一个JVM内存中其只有一份,此作用域
 *        通常还会配置@Lazy注解一起使用,一般可重用对象可设计为单例作用域,对于这样的对象,spring
 *         框架不仅仅负责其创建,还会存储到bean池
 *    2)prototype(多例作用域-此作用域对象何时需要何时创建,spring可以对其初始化,但spring框架不负责销毁)
 *     一般不可重用对象,或者说只是用一次就不再用此对象了,这样的对象可设计为多例作用域
 *    
 */ 
//@Scope //spring容器中的bean没有使用@Scope注解描述是默认就是单例
//@Scope("prototype")
//@Lazy
//@Lazy  //默认value属性值为true,表示此对象要延迟构建及初始化
//@Lazy(false)   //这里假如要写false,跟没写@Lazy注解一样,表示不支持对象延迟构建及初始化
//@Component  ////此注解描述bean表示这个bean对象会由spring创建,其名字默认为类名首字母小写.
public class ObjectPool { //bean的名字为类名首字母小写 obejctPool
    public int size;
    
    public ObjectPool() { //constructed method execute了,说明 object 创建 了
        System.out.println("构造方法-- ObjectPool().......................");
    }
    
    
    
    /**
     * @PostConstruct 此注解描述的方法为生命周期初始化方法,此方法会在对象创建之后执行(是对象创建以后的初始化)
     * 在这样的方法中一般会为创建好的对象在此进行一些初始化操作
     */
    @PostConstruct
    public void init() {
        System.out.println("init().........");
        
    }
    /**
     * @PreDestroy 此注解描述的方法为生命周期销毁方法,此方法会在对象销毁之前执行,
     * 在这样的方法中可以实现一些资源销毁操作
     */
    @PreDestroy
    public void destory() {
        System.out.println("destory()..........");
    }

}

其中:

  • @Scope 是Spring中用于定义Bean对象作用域的一个注解,其常用的值有

singleton(整个内存有一份Bean实例,此实例何时创建与类的延迟加载特性配置有关,此实例创建以后,生命周期会由spring框架管理),prototype(每次获取都会创建新实例,此实例会在需要时创建与lazy特性无关,这个实例创建以后,不会交给spring管理,spring可以对其初始化,但不负责销毁。)等。

  • @Lazy注解用于描述类,其目的是告诉spring框架此类支持延迟加载,通常会配合单例作用域使用。
  • @PostConstruct 注解用于描述bean对象生命周期方法中的初始化方法,此方法会在对象的构造方法之后执行。
  • @PreDestroy 注解用于描述Bean对象生命周期方法中的销毁方法,此方法会在对象销毁之前执行(当作用域为prototype时,此方法不会执行)。

第五步:通过测试类测试作用域,延迟加载,生命周期方法。

package com.cy.pj.common.pool;
/**
 * SpringBoot 2.x 工程下的测试类的有什么特点?
 *  1)包结构(启动类所在包或子包)
 *  2)注解描述(@SpringBootTest)
 *  
 *  
 *  
 *  
 *  SpringBoot 2.x 工程下的测试方法有什么特点?
 *   1)单元测试方法使用@Test注解(org.junit.jupiter.api.test)进行描述
 *   2)单元测试方法不能使用private访问修改符
 *   3)单元测试方法的返回值类型只能是void
 *   4)单元测试方法不允许写方法参数
 *   5)单元测试方法允许抛出异常
 *   
 *   SpringBoot单元测试类中如何为属性进行值的注入?
 *   1)单元测试类使用了@SpringBootTest注解描述
 *   2)单元测试类中的属性使用了Spring框架中的指定注解进行描述(例如:@Autowired)
 */


import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

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

@SpringBootTest
public class ObjectPoolTests {
    @Autowired
    private ObjectPool objectPool1;
    
    @Autowired
    private ObjectPool objectPool2;
     
    @Test
    void testObjectPool() {
        System.out.println("testObjectPool()1="+objectPool1);
        System.out.println(objectPool1==objectPool2); //  比较对象地址    true 
        objectPool1.size = 10;
        System.out.println(objectPool2.size);
    }
    

}

Spring框架管理Bean对象有什么优势?
Spring 是一个资源整合框架(Framework),通过spring可将很多资源(自己写的对象或第三方提供的对象,例如连接池等)整合在一起,然后进行科学应用,以便更好的对外提供服务。如图所示:
b.png
在上图中,Spring框架可以为由它管理的对象(Bean)提供懒加载策略(对象暂时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时可以考虑内存中只有一份,prototype-使用次数少时可以用时创建,不用时销毁),生命周期方法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的有效使用。同时Spring框架还可以基于用户设计管理对象与对象的依赖关系,以降低对象与对象之间的直接耦合,提高程序的可维护性和可扩展性。

3.4 项目业务增强实现及测试
第一步:定义业务Cache接口.

package com.cy.pj.common.cache;

public interface Cache {

}

第二步:定义WeakCache实现Cache接口.

package com.cy.pj.common.cache;

import org.springframework.stereotype.Component;

@Component
public class WeakCache implements Cache {

}

第三部,定义SoftCache实现Cache接口.

package com.cy.pj.common.cache;

import org.springframework.stereotype.Component;

@Component //bean对象默认名字为类名,首字母小写
public class SoftCache implements Cache {

}

第四步:单元测试类


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

@SpringBootTest
public class CacheTests {
    //@Autowired注解描述属性时,系统底层会基于属性类型从spring容器查找对象,假如有多个
    //类型都满足注入要求,则还会基于属性进行查找,检测哪个bean名字与属性名相同
    //假如有相同的则直接取相同进行注入,没有则抛出异常
    @Autowired
    //@Qualifier注解必须配合 @Autowired注解使用,
    //用于指定将哪一个bean名字对应的对象注入给描述的属性(例如cahce属性)
    @Qualifier("weakCache")
    
    private Cache cache;
    @Test
    void testCache(){ //不写测试方法修饰符也默认为public
        System.out.println("cache="+cache);
        
    }
    

}

业务测试运行原理分析,如图-所示:

思考:

  1. @Autowired注解应用规则?
  2. @Qualifier注解的作用是什么?

@Autowired由spring框架定义,用于描述类中属性或相关方法。Spring框架在项目运行时假如发现由他管理的Bean对象中有使用@Autowired注解描述的属性或方法,可以按照指定规则为属性赋值(DI)。其基本规则是:首先要检测容器中是否有与属性或方法参数类型相匹配的对象,假如有并且只有一个则直接注入。其次,假如检测到有多个,还会按照@Autowired描述的属性或方法参数名查找是否有名字匹配的对象,有则直接注入,没有则抛出异常。最后,假如我们有明确要求,必须要注入类型为指定类型,名字为指定名字的对象还可以使用@Qualifier注解对其属性或参数进行描述(此注解必须配合@Autowired注解使用)。具体过程可参考图-18的设计进行自行尝试和实践。

4 Spring Boot 小节总结

4.1 重难点分析
(1)Spring boot 是什么? 框架,也可以看成是框架脚手架,做了架子工要做的事情-搭建项目基础骨架的工作人员
(2) Spring boot 核心优势?(启动依赖,自动配置-开箱即用,健康检查-系统监控)
(3) Spring boot 项目的创建方式?( https://start.spring.io)
Spring boot项目启动时,Bean的初始化过程是怎样的?(查找,加载,读和存储配置,创建和存储实例对象)
(4) Spring boot 项目启动时,Bean对象的依赖注入过程是怎样的?(标记,查找,注入)
(5) Spring 框架中的Bean对象有什么特性?(延迟加载,作用域,生命周期方法)
(6)Spring 框架中单例(singleton)作用域对象特点,应用场景(频繁用)?
特点: 默认为单例作用域-类的实例在一个JVM内存中其只有一份,此作用域通常还会配合@Lazy注解一起使用。
when use 单例作用域?
一般可重用对象可设计为单例作用域,对于这样的对象,spring
框架不仅仅负责其创建,还会存储到bean池。
(7)Spring 框架中多例(prototype)作用域对象特点,应用场景(稀少用)?
特点: 多例作用域-此作用域对象何时需要何时创建,spring框架可以对其初始化,但spring框架不负责销毁。
when use 多例作用域?
一般不可重用对象,或者说只是用一次就不再用此对象了,这样的对象可设计为多例作用域


人忘七年°
4 声望2 粉丝