• java学习day41--Spring Boot(一)入门


    Spring Boot(一)--入门

    Spring Boot简介

    ​ SpringBoot就是一个javaweb的开发框架,和SpringMVC类似,对比其他javaweb框架的好处,官方说是简化开发,约定大于配置, you can "just run",能迅速的开发web应用,几行代码开发一个http接口。

    发展过程: Java企业级应用->J2EE->spring->springboot

    ​ Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。

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

    Spring Boot 核心特性

    ​ Spring boot是一个脚手架(而非框架),构建于Spring框架(Framework)基础之上,基于快速构建理念,提供了自动配置功能,可实现其开箱即用特性(创建完一个基本的项目以后,可零配置或者少量配置即可运行我们的项目),其核心主要有如下几个方面:

    起步依赖(Starter Dependency)。

    自动配置(Auto Configuration)。

    健康检查(Actator)-监控。

    Spring Boot的主要优点:

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

    Spring Boot 环境配置

    工具下载以及配置

    下载JDK1.8,并进行环境变量配置(假如已有则无需再次下载和配置)。

    下载最新maven(例如apache-maven-3.6.3,网址http://maven.apache.org/)并解压。

    下载sts最新版(jar包需要java -jar命令解压或者直接双击)

    创建一个新的工作区

    配置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>
    

    STS整合maven

    两个地方需要配置:

    Maven --> Installations

    Maven --> User Settings

    Spring Boot 快速入门

    项目创建及结构分析

    打开STS 集成开发工具,创建spring boot项目,其具体步骤如下:

    第一步:打开项目新建窗口(快捷键ctrl+n), 搜索spring,选择spring starter 项目

    第二步:填写Service URL :https://start.spring.io以及其他的基本项目信息

    注:这里可能会出现超时,如果出现超时,最简单的办法就是更换一下URL为:https://start.aliyun.com

    问题就可以解决,或者换一个网络

    第三步:选择Spring Boot版本(可以选择最新的版本,但是不要选择测试的版本)

    ​ 点击finish之后,项目便开始从maven配置中指定的私服服务器(例如阿里云的maven服务器)去下载起步依赖(SpringBoot项目中默认指定了项目启动时需要的一些jar包依赖),这个过程可能会比较耗时(网络最好不要用手机网络,会导致很多资源下载不下来),假如指定版本的springboot项目以前创建过,它会默认先从本地库查找,假如本地库没有,则从远程库去下载。

    ​ 项目结构中,所有的类和配置文件都是创建好项目以后,由STS工具帮我们自动创建的。

    项目启动过程分析(了解)

    springboot项目启动的时候发生了什么?

    ​ SpringBoot 项目在启动时,首先基于启动入口类上的注解描述,进行自动配置并扫描指定包以及子包中的类进行加载,然后检测类上是否有Spring框架中指定的注解描述(例如@Component,@Controller,@Service 等)。假如有,则将类交给Spring框架中的BeanFactory工厂接口的实现类对象,此工厂对象会基于反射创建Bean的实例,假如此Bean指定了生命周期方法,还会调用生命周期方法。当实例创建以后,Spring框架还会基于类的作用域描述,将实例存储到不同作用域的容器中。以实现Bean对象的科学应用。

    1593436571449

    项目业务初步实现及测试

    注意:springboot启动类:

    package com.cy;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 由此注解@SpringBootApplication描述的类为springboot项目的启动入口类
     * 记住: springboot的启动入口类只能有一个
     * 	spring boot项目的启动入口类需要使用@SpringBootApplication注解进行描述
     */
    @SpringBootApplication
    public class CgbSpringboot01Application {
        public static void main(String[] args) {
            SpringApplication.run(CgbSpringboot01Application.class, args);
        }
    
    }
    

    @SpringBootApplication

    作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

    • spring boot项目的启动入口类需要使用@SpringBootApplication注解进行描述
    • springboot的启动入口类只能有一个

    FAQ分析

     /* FAQ:常见问题
     * 	1 这个类在启动时会做哪些事
    	  	a 加载类(将类的信息从磁盘读到内存):线程+IO
    	    b 创建字节码对象,(其类型为Class类型)用于存储类的字节码信息
    		c 基于字节码对象获取类上的注解信息,判定此类是否要交给spring管理
    		d 假如是交给spring管理的对象,spring框 架会创建其对象然后赋子其特性。
    		e 基于配置文件(application.properties)以及springboot提供的自动配置对对象进行初始化应用。
    	2 请问如何验证启动类在启动在启动时加载了哪些类?(借助JVM参数进行分析)
    		a 类加载分析过程参数-XX:+TraceClassLoading(+代表有效参数)
    		
    	3 在springboot项目中自己的业务代码写到哪里?如何交给spring去管理?
    		a 所有的业务代码写到src/test/java目录中启动类所在的包或者子包中
    		b 将这些类使用特定注解进行描述(例如 @Commpent @Service ....)
    	4 在springboot中我们自己的Java业务测试代码写到哪里?有什么特点?
    		所有测试代码写到src/test/java目录中启动测试类所在包或者子包中
     		所有测试类使用@SpringBootTest注解
    		所有测试方法使用import org.junit.jupiter.api.Test中的@Test注解;
    	*/	
    

    业务实现:

    基于SpringBoot脚手架,通过Spring框架进行Bean对象的管理实现。

    第一步:创建一个DefaultCache类然后交给spring 管理。

    package  com.cy.pj.common.cache;
    @Component   
    public class  DefaultCache {}
    

    其中,@Component是Spring中用于描述Bean类的一个注解。用于告诉Spring这个类的实例由Spring创建,当此对象由Spring创建和管理时,默认会将对象存储到池(Bean池)中。

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

    package com.cy.pj.common.cache;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.stereotype.Component;
    
    //springboot项目中所有的单元测试类都使用@SpringBootTest注解来描述
    @SpringBootTest
    public class DefaultCacheTests {
    
        @Autowired
        private DefaultCache defaultCache;
        //所有单元测试方法的Test注解都使用import org.junit.jupiter.api.Test;
        @Test
        public void  testCache() {
            System.out.println(defaultCache);
        }
         /**
    	  * 分析:
    	  * 1.假如在16行输出defaultCache的值为null,可能的原因是什么?
    	  * 1)defaultCache属性上没有使用@Autowried相关注解描述?
    	  (spring不认为这个属性的值由它进行注入)
    	  * 2)单元测试类上没有使用@SpringBootTest注解描述
    	  * 3)Test注解类所在包检测是否有问题,测试类的位置(例如包结构)是否有问题?
    	  * 
    	  * 2.假如defaultCache的单元测试中出现NoSuchBeanDefinitionException异常,
    	  * 其类型为com.cy.pj.common.cache.DefaultCache这个bean对象找不到,请问
    	  * 原因可能是什么?
    	  * 1)DefaultCache所在的包不在启动类所在包或者子包中。
    	  * 2)DefaultCache类没有使用spring指定注解进行描述。
    	  */
    
    }
    

    其中:

    • @SpringBootTest 注解用于告诉spring框架,此测试类交给spring管理。
    • @Autowired注解描述属性时,用于告诉spring框架要为此属性注入一个值?(至于注入规则,后面课程慢慢加强)

    第三步:代码设计及运行分析,如图所示:

    1593418782074

    在图中描述了DefaultCacheTests类与DefaultCache类的关系,这两个类通过指定注解(@SpringBootTest,@Component)进行了描述,其意图是告诉spring框架这个两个类的实例的创建由Spring负责,并且由Spring框架基于@Autowired注解的描述完成DefaultCacheTests实例中有关DefaultCache类型的值的注入(DI)。

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

    Spring 管理bean对象,会为bean赋予什么特性?这些特性有什么好处?

    延迟加载(按需加载,懒加载)特性-暂缓对象的创建,何时需要何时创建?

    • a)优点:可以优化资源的使用。
    • b)缺点:用时在创建可能会导致响应速度降低。
    • c)场景:资源有限,大对象,稀少用能懒加载就懒加载。
    • d)实现:在需要懒加的对象类型上使用@Lazy注解进行描述

    作用域(Spring框架为对象提供的作用范围,对象的生命周期只能在指定范围有效)

    • a)优点:让对象在有效范围发挥作用,尽量控制对象的创建和销毁以保证对象的高效,低耗的运行。

    • b)缺点:框架底层设计难度会加大,应用不熟练会导致作用域冲突。

    • c)场景:不同业务,作用域的设计也不同?(例如 对象在整个项目中应用非常频繁可以考虑单例作用域。)

    • d)实现:在需要设定作用域的类上使用@Scope注解进行描述。

        d.1)**@Scope("singleton") 单例作用域**,此作用域的对象在这个内存只有一份,通过
      

      共享设计(bean池),实现对象的可重用性。此对象何时创建由懒加载(Lazy)特性

      设计决定,是否可以被销毁由spring框架决定(一般是在容器销毁时销毁)。适合

      频度应用比较高的对象。

      d.2)@Scope("prototype") 多例作用域,此作用域的对象在需要时创建(与懒加载特性无关),

      每次从容器获取都是一个新的对象,且这些对象spring框架不负责销毁。适合应用频度比

      较低的对象。

    生命周期方法(每个对象都有生命周期,但不见得每个对象都会设置生命周期方法)

    • a)如何理解生命周期方法?生命周期方法是在对象生命周期过程中要执行的一些方法。
    • b)设计生命周期方法的目的?对象生命周期的不同阶段执行不同业务(例如servlet init,service,destory)
    • c)Spring如何设计Bean对象生命周期方法?spring框架中使用相关注解对象对生命周期方法进行描述。
     	   **@PostConstruct** 
     此注解描述生命周期初始化方法,在构造方法执行之后执行,用于实现一些资源的初始化操作
        **@PreDestroy** 
    此注解描述生命周期销毁方法,在对象销毁之前执行,当作用域为prototype时,此方法不会执行
    

    实例代码

    package com.cy.pj.common.pool;
    import javax.annotation.PostConstruct;
    import javax.annotation.PreDestroy;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    @Component
    //@Lazy
    //@Scope("singleton") 默认,没有指定scope的时候默认就是singleton作用域
    //@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    //@Scope("prototype") //多例
    public class ObjectPool {//一个普通的对象池对象
    	public ObjectPool() {
    		System.out.println("==ObjectPool()==");
    	}
    	@PostConstruct 
    	//此注解描述生命周期初始化方法,在构造方法执行之后执行,
    	//用于实现一些资源的初始化操作
    	public void init() {
    		System.out.println("==init()==");
    	}
    	@PreDestroy //此注解描述生命周期销毁方法,在对象销毁之前执行
    	public void destory() {
    		System.out.println("==destory()==");
    	}
    }
    

    测试方法

    package com.cy.pj.common.pool;
    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 objectPool01;
    	@Autowired
    	private ObjectPool objectPool02;
    	@Test
    	void testObjectPool() {
    		System.out.println(objectPool01==objectPool02);//false
    	}
    	
    }
    

    spring管理bean对象的好处

    ​ spring 是一个资源整合框架(Framework),通过spring可将很多资源(自己写的对象或第三方提供的对象,例如连接池等)整合在一起,然后进行科学应用,以便更好的对外提供服务。如左下图:

    1593428220402

    Spring框架可以为由它管理的对象(Bean)提供懒加载策略(对象暂时用不到,则无需加载和实例化),作用域(例如singleton-频繁用时可以考虑内存中只有一份,prototype-使用次数少时可以用时创建,不用时销毁),生命周期方法(更好实现对象的初始化和资源销毁),以实现对象对系统资源的有效使用。同时Spring框架还可以基于用户设计管理对象与对象的依赖关系,以降低对象与对象之间的直接耦合,提高程序的可维护性和可扩展性

    项目业务增强实现及测试

    第一步:定义业务Cache接口

    package com.cy.pj.common.cache;
    public interface Cache {
    
    }
    

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

    package  com.cy.pj.common.cache;
    import org.springframework.stereotype.Component;
    @Component 
    //@Component("cache")//假如没有起名,默认为类名,然后首字母小写,例如weakCache
    //如果此处起名了,那么创建该对象的实例的名字就是cache,而不是默认的
    public class WeakCache implements Cache{
    
    }
    

    第三步:修改DefaultCache,让此类也实现Cache接口,关键代码如下:

    package com.cy.pj.common.cache;
    @Component
    public class DefaultCache implements Cache{
    //TODO
    }
    

    第四步:单元测试类

    package com.cy.pj.common.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
            @Qualifier("defaultCache")
            private Cache cache;
    
            @Test
           public void testCache() {
                System.out.println(cache);
            }
    }
    

    业务测试运行原理分析:

    ![img](file:///C:/Users/14354/Desktop/CGBIII-%E8%AF%BE%E5%89%8D%E8%B5%84%E6%96%99/DOCS/01-01-CGB-SPRINGBOOT%E5%85%A5%E9%97%A8/images/image12.png)

    思考:

    @Autowired注解应用规则?

    规则:先基于属性类型查找对象进行注入,假如类型有多个,再基于属性名字进行注入

    @Qualifier注解的作用是什么?

    配合@Autowired注解使用,按bean名字进行值的注入。

    详细说明:

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

    出现问题以及解决方式:

    问题1:不能确定唯一的bean,依赖注入失败:NoUniqueBeanDefin
    itionException

    Caused by:
    org. springframework. beans . factory . NoUniqueBeanDefin
    itionException: No qualifying bean of type
    ' com. cy.pj . common. cache .Cache ' available: expected
    single matching bean but found 2:
    defaultCache , weakCache
    

    问题分析以及解决:

    1 检查哪里对Cache进行了引用。
    2 检查对Cache引用时使用的注解描述。
    3 检查容器中Cache接口下实现类对象的定义(是否有多个?)。
    

    问题2:找不到对应的bean对象

     org-springframework.beans.factory.NoSuchBeanDefinitionException:
     No bean named 'dafaultCache' available
    

    问题分析以及解决:

    1 检查你获取的这个对象实例的类型是否使用了特定注解描述
    2 检查你获取的这个对象实例的类型所在的包是否正确
    3 假如是基于Bean的名字进行Bean对象的获取,要检测Bean的名字是否正确。
    

    问题3:依赖注入失败:UnsastishedDependengyException

    org.springframeworkbe as.factory.UnsastishedDependengyException: Error creating bean with name 'com.cy.pj.common.cache.DefaultCachests': Unsatisfed dependengy expressed through feld '
    
    

    问题分析以及解决:

    1 检查错误代码中自己定义的类(例如DefaultCacheTests)中的属性
    2 基于错误分析,哪个属性的值在进行依赖注入时失败了(例如DefaultCache)
    3 检查注入失败的属性对应的对象是否交给了Spring管理(例如是否有特定注解描述,包结构是否正确)。
    
  • 相关阅读:
    重测序(RADseq)做群体遗传分析套路
    BSA分析
    GWAS初探
    GWAS在农业上应用
    【Python小试】计算目录下所有DNA序列的Kmer并过滤
    dict['source'] = list[1],出现这种情况大多是数据的格式发生错误
    First Wainberg-2018-Deep learning in biomedicine Experience
    Second LearningConvolutionalNeuralNetworksforGraphs Experience
    从windows本地IDE启动远程Linux文件进行调试
    xshell的一些基本操作
  • 原文地址:https://www.cnblogs.com/liqbk/p/13221455.html
Copyright © 2020-2023  润新知