Spring boot基本使用及 stater机制原理

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring boot基本使用及 stater机制原理相关的知识,希望对你有一定的参考价值。

前言

之前得文章主要介绍得spring以及springmvc,其实整个文章主要介绍的是spring 创建bean 以及各个对bean实例创建过程中的各个部分扩展,以及spring mvc 如何处理http请求,然后并使用 handler对于 各个请求的匹配到controller 上 ;这篇文章 继续 对spring boot 进行深入研究,从 spring boot 搭建开始 到如何使用 ,以及 stater机制 怎么会有约定大于配置的说法 ,极大的简化我们的开发。

SpringBoot 基本使用

首先 对于一般的业务系统的开发 ,无非关心的是几个 点, 搭建框架 的效率,代码的规整以及 是否易于管理扩展,以及 系统扩展性,日志系统的管理 查看,以及 安装部署项目以及 jar包 配置文件 的管理情况。 这些在spring boot没有出来前,怎么样搭建一个项目 ,而这个项目 要 达到上面所有的效率, 对于一般的开发工程师 是比较困难 的 因为需要对于 一般的程序开发人员,我们并不想了解 框架底层,那是很耗费时间和学习精力的。所以 出现了SpringBoot框架 ,这个框架利用约定大于配置的思想,对于我们开发是非常大的提升解决对于框架的提升和理解,也是SpringBoot为什么这么火的原因。

快速上手

Spring Boot

官网对于springboot的介绍:

Spring Boot 可以轻松创建可以“直接运行”的独立的、生产级的基于 Spring 的应用程序。 我们对 Spring 平台和第三方库持固执己见的看法,因此您可以轻松上手。大多数 Spring Boot 应用程序需要最少的 Spring 配置。 如果您正在寻找有关特定版本的信息,或有关如何从早期版本升级的说明,请查看我们 wiki 上的项目发布说明部分。

 在idea中有springBoot插件 可以快速创建 项目 

 也可以直接在官网上直接创建 项目

Spring Initializr

当然也可以完全手动创建 新建普通java maven工程 引入maven依赖 编写启动类  也比较简单的。   

快速跑起来  直接使用 RestConllector  就可以快速的将框架起来

 约定俗成的规则

Bean扫描的basePackage为启动类所在包 配置参数通过classpath下的application.properties或application.yml来配置 web开发的静态资源文件可放在classpath下的static、public.resources、 META-NF/resouces目录,访问的url对应它们之下的目录结构。四个目录的搜索次序:/META-INF/resources>resources>static>public web开发采用页面模板技术时,模板文件放在classpath:/templates目录下

打包 和运行

 构建的依赖 添加 maven-plugin 

构建可执行Jar

构建:maven package   执行:java -jar xxx.jar 构建war: 1修改打包方式: war 2移除内嵌tomcat的依赖 3修改启动类继承SpringBootServletInitializer,实现configure方法。这里实际是创建了一个 DispatcherServlet
<groupId>courseware.springboot.ssm</groupId>
    <artifactId>ssm-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <name>ssm-demo</name>

初始化器 将 这个 springbootapplication  给绑定进去。
@SpringBootApplication
public class DeviceManagerApplication extends SpringBootServletInitializer 

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

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) 
		return builder.sources(DeviceManagerApplication.class);
	

 如果不绑定  servlet是不知道配置的数据库信息 等等。

可以看一下 这个类中的 创建 context方法进行绑定其他数据 

这里面的 父类  parent 依赖给我们加了很多   以及  现在的  赋值

继续往上面看  包括 mq redis  等等  依赖包都给我们 db  等等 扩展包  都在这里面给我们引入了

这里面 为了方便管理 以及 冲突问题, 所以 版本号初始化在更新的,而我们想修改版本号 则自己要设置新的版本号。

@SpringBootApplication

 @SpringBootApplication 这个注解  主要就两个注解重要 @SpringBootConfiguration 和 @EnableAutoConfiguration 注解

SpringBootConfiguration 注解

 上面有 configuration  所有的配置类注解 

 对于EnableAutoConfiguration  注解  则   进去  查看   AutoConfigurationImportSelector   导入 类 ,并 

将 beanfactory引入进来   扫描AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);  判断 是什么类型  是servlet  或者 webflus 的类型的 

 

 右键启动时,启动起来 会加载  SpringBootApplication 里面的所有的东西。 包括 配置文件。

Spring Boot日志

Java日志框架: 常见的日志框架很多:JCL、SLF4J、Jboss-logging、jUL、log4j、log4j2、logback等等 一般日志是由一个抽象层+实现层的组合来搭建的,一个应用中各组件用的日志框架可能不同 java日志组件介绍(common-logging,log4j,slf4j,logback ) - 疯狂的java - BlogJava

因为java 各自有各自一套日志打印工具,所有是很麻烦的。这里用 桥接的方式,将 日志进行输出。

SpringBoot日志框架: Spring Boot使用Commons Logging记录内部日志,但底层日志实现保持开放状态。 提供了 Java Util Logging Log4J2 Logback的 默认配置 Stater方式,默认使用Logback实现进行日志记录,加入适当的路由确保其他日志框 架的正常工作 一般情况会集成其他框架,这些框架会带有自己的日志框架,我们只需要排除即可

我们在使用 logback 或者 log4j 打印日志时,就可以输出

SpringBoot日志配置: application.properties中的属性配置 日志文件配置 resource目录下的logback.xml配置示例
# 日志配置
# 指定日志文件
logging.file.name=my.log
# 指定日志目录
logging.file.path=/app/log
# 调整日志级别
logging.level.root=info
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
<configuration>
       <appender name="filelog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>/logs/app.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/logs/app.%d.%i.log</fileNamePattern>
            <maxHistory>30</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy    
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> 
            <maxFileSize>1MB</maxFileSize> 
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder> 
        <pattern> %d %p (%file:%line\\)- %m%n </pattern> 
         <charset>UTF-8</charset> <!-- 此处设置字符集 --> 
        </encoder>
     </appender>
    <root level="debug">
        <appender-ref ref="filelog" />
     </root>
</configuration>

 测试

现在越来越多的时间 写单元测试了。其实写单元测试是太慢了,所以才不愿意写单元测试,但是springboot提供的工具是越来越强大的。

SpringBoot测试框架: Spring Boot提供了许多实用程序和注解来测试应用 Spring的测试包含spring-boot-test和spring-boot-test-autoconfigure两个模块 一般使用spring-boot-starter-test使用测试框架,引入了test模块及JUnit Jupiter, AssertJ,Hamcrest等库

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
        </exclusion>
    </exclusions>
</dependency>

 Actuator

Spring Boot Actuator SpringBoot单体 应用 监控-Actuator 预生产环境监视管理应用程序,可以通过HTTP端点、JMX方式进行管理监视。可以自动做到应用审计、健康检查、指标收集。 开启生产功能Actuator pom.xml配置 application.properties配置
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# 启用端点,默认不启用,还可以单独的指定见 shutdown的示例
management.endpoints.enabled-by-default=true
# 启用shutdown端点
management.endpoint.shutdown.enabled=true
# *表示在http上暴露所有端点,指定端点名表示暴露指定的端点
management.endpoints.web.exposure.include=*
# 默认值为never,显示所有组件的详细健康信息
management.endpoint.health.show-components=always
management.endpoint.health.show-details=always
# 禁用HTTP暴露端点
# management.server.port=-1

 Production-ready Features (spring.io)

Actuator暴露的Http端点 查看所有暴露端点:/actuator 访问health端点:/actuator/health bean信息:/actuator/beans 指标信息:/actuator/metrics RequestMapping信息:/actuator/mappings 线程堆栈:/actuator/threaddump 自定义暴露端点 这个指标的打印信息。查看监控等。 

这些都可以用监控去查看 所有的信息。

SpringBoot Stater

Spring Boot的特性(优点 )使创建一个基于Spring的应用很简单 ,Starter简化构建依赖配置,自动配值,零xml配置 而产生 spring boot 这么大的优点 都是来自 stater来 做的。 如果不使用spring boot,搭一个SSM是非常麻烦的。 传统的搭建 项目方式。 1.加入相关的jar包 2.配置web.xml,加载spring和spring mvc 3.配置数据库连接、配置spring事务 4.配置加载配置文件的读取,开启注解 5.配置日志文件 配置完成之后部署tomcat调试 最主要的难点 包依赖  bean 配置。 而Spring Boot  这些都做了的。 Starter的作用: starter 引入相关的jar starter自动完成bean配置 所有的datasource  这些都是自动给我们自动注入进去的。 也是我们在启动应用常见报错 datasource.url 找不到给我们报的错。 这里以 mybatis为例,查看到的   包括引入的 auto config 和mybatis 引入进来。 这里面从stater里面引入的。

 

这里重要的是 在 auto-config中 spring.factories  中需要配置  对应的configuration

自己引入下来的 包括下面 对应依赖 的  autoconfigure 和 stater文件

 

这里面最重要的就是 autoconfigure  

然后 默认 文件的路径 resuource下面的 spring.factories

 这里面  mybatis 配置的 地方  有  扩展 以及  拦截等等。  初始化  typehandler  类型适配器 等等,在初始化参数时就创建好。

 在mybatis中重要的一个就是sqlsession

通过@org.springframework.context.annotation.Configuration 和 @Bean  注解  来 注入SqlSessionFactory

 

 进行转换为   这里面将spring的 ibatis转换成 mybatis需要的bean。

 

 在 整个类上 有的注解@ConditionalOnClass( SqlSessionFactory.class, SqlSessionFactoryBean.class )含义是 只有这两个类存在时,才会加载,相当于做了个校验, 判断 当不存在时就会抛出异常

以及  

这里面 的注解 引入 datasource 类, 并且引入 MybatisProperties    配置,对应的属性文件配置这些。

@AutoConfigureAfter(DataSourceAutoConfiguration.class)  这里面 表示就是 有顺序的概念, 只有前面的加载成功,才能加载后期的。

自动配置-―条件依赖注解

@ConditionalOnClass @ConditionalOnMissingClass @ConditionalOnBean @ConditionalOnMissingBean @ConditionalOnProperty @ConditionalOnResource @ConditionalOnWebApplication @ConditionalOnNotWebApplication @ConditionalOnExpression @AutoConfigureAfter @AutoConfigureBefore @AutoConfigureOrder 指定顺序

对于datasource  这些配置前缀 和属性 就是来自@EnableConfigurationProperties  这个的

 配置datasource需要数据库连接参数,mybatis也有自己的配置参数  然后所有的properties都是在 @EnableConfigurationProperties 中进行绑定的。

这些bean配置  都是通过 @bean @configuration  @import 来引入的。

Spring Boot Starter 

写一个starter  就是为了简化使用。

Starter是一个集成接合器,完成两件事          引入相关的jar         自动配置   Spring boot规范:           starter.jar完成引入相关的jar         autoConfigure.jar完成自动配置

其实也自己做的话就一个jar包就可以,不用拆分成 两个 用 pom来引入  然后在写autoconfigure

Starter命名规范   Spring提供的starter:         spring-boot-starter-xxx-x.y.z.jar         spring-boot-xxx-autoconfigure-x.y.z.jar 第3方的starter:           Xxx-spring-boot-starter-x.y.z.jar           xxx-spring-boot-autoconfigure-x.y.z.jar 动手制作一个第3方lib的starter —∶准备第3方的jar 二︰制作starter
  • 1建工程 maven项目就行 也不用其他 mvc项目什么的。
  • 2引入spring-boot-start.spring-boot-autoconfigure、第三方jar
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.3.5.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-autoconfigure</artifactId>
      <version>2.3.5.RELEASE</version>
    </dependency>
    <!--用来生成元数据-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <version>2.0.6.RELEASE</version>
    </dependency>
像这些在 其他的spring starter中都可以拿到
  • 3如需要生成配置元信息,加入spring-boot-configuration-processor依赖
  • 4编写自动配置类
@ConfigurationProperties(prefix = "boy")
public class BoyProperties 
    /**
     * 姓名
     */
    private String name;
    /**
     * 年龄
     */
    private int age;
    /**
     * 长度
     */
    private int length;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public int getAge() 
        return age;
    

    public void setAge(int age) 
        this.age = age;
    

    public int getLength() 
        return length;
    

    public void setLength(int length) 
        this.length = length;
    

@Configuration
//@ConditionalOnBean()
//@ConditionalOnMissingClass()
@EnableConfigurationProperties(BoyProperties.class)
public class BoyAutoConfiguration implements InitializingBean 
    
    @Bean
    public BoyService buildBoyService(@Autowired BoyProperties bp) 
        BoyService service = new BoyService();
        service.setName(bp.getName());
        service.setAge(bp.getAge());
        service.setLength(bp.getLength());
        return service;
    

    @Override
    public void afterPropertiesSet() throws Exception 
        // todo init 
    

在pom中 你只需要做想要的jar包依赖就行。

  • 5配置发现配置文件:META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=springboot.c.BoyAutoConfiguration
  • 6打包发布

 在pom中添加发布插件就行

这些注解  都可以在 jar包中可以看到。

 

 AutoConfiguration

 SpringBoot参数配置规则

classpath:/下的application.properties / application.yml中   可以配置参数 这些是都可以变得。 官网上 对于这个并不一定要求在这个位置下叫这个名字, 可以进行扩展。 Core Features (spring.io)

 Spring Boot 允许您将配置外部化,以便您可以在不同的环境中使用相同的应用程序代码。您可以使用各种外部配置源,包括 Java 属性文件、YAML 文件、环境变量和命令行参数。 属性值可以通过使用 @Value 注释直接注入到你的 bean 中,通过 Spring 的 Environment 抽象访问,或者通过 @ConfigurationProperties 绑定到结构化对象。 Spring Boot 使用一个非常特殊的 PropertySource 顺序,该顺序旨在允许明智地覆盖值。属性按以下顺序考虑(较低项目的值覆盖较早的项目)

 参数配置文件的约定放置位置(优先级从高到低)为:

  • 运行程序的当前工作目录下的config子目录file:./config
  • 运行程序的当前工作目录file:./
  • classpath:/config子目录
  • classpath:/根目录

 其实这样做得好处还是在 jar包外面 找 配置文件, 其实就是为了扩展 修改配置文件。

方便线上维护和修改等等。

 

ConfigFileApplicationListener 类 中 是设置 spring boot 得配置文件路径

 这里面帮我们看到了设置的参数。

 从最后一个往前匹配的路径  并且 application 是默认配置文件名字

 

在自动配置名字  位置 以及 额外添加 目录,这些都可以 在这里面看到

 

设置 这些参数的优先级 以及怎么指定  是最近到最远 进去检查的。

  •  程序命令行参数:--spring.config.name=xXXX
  • JVM参数:-Dspring.config.name=xXXX
  • 操作系统环境变量: spring.config.name=xxXX
$ java -jar myproject.jar --spring.config.name=girl
$ java -jar myproject.jar --spring.config.location=classpath: /default.properties,classpath:/override.properties
spring.config.location属性配置
  • spring.config.location指定配置文件所在目录(以/结尾)或文件名,可多值(逗号间隔)
  • 查找的顺序是配置的反序

这里怎么查看的, 都是可以配置的。

spring.config.name属性配置
  •  spring.config.name可多值(逗号间隔)
  • 属性查找的顺序是配置的反序

spring.config.additional-location属性 配置
  • 除了默认规则外用来指定额外补充的配置文件目录或配置文件
  • 优先级高于spring.config.location

 @PropertySource  等容器加载完毕  在去加载 配置文件 这个 会将之间加载的属性给覆盖掉 

并且在 配置文件中 

你的配置中需要随机值,可通过 RandomValuePropertySource源获得随机 的int、long、 uuid、字符串
my.secret=$random.value
my.number=$random.int
my.bignumber=$random.long
my.uuid=$random. uuid
my.number.less.than.ten=$random.int(10)
my.number.in.range=$random.int[1024,65536]
参数值加密 password=eadesdrefdaf8efacnanaeijr91qw: 实现一个EnvironmentPostProcessor,在里面完成密文值的解密 将这个实现加到META-INF/spring.factories 中,让其生效
org.springframework.boot.env.EnvironmentPostProcessor=com.example.YourEnvironmentPostProcessor

对于资源的加载 

YAML语法

YAML最最基础语法_vincent_hbl的博客-CSDN博客_yaml语法

参数使用

  •  方式一: @Value("$my.name")  这也是常见的 属性注入检测
  •  注入Environment bean
  •  方式三:@ConfigurationProperties(prefix = "my")
加在一个bean类上,给bean的属性进行赋值,属性需有getters and setters 有两种具体用法

 

 @ConfigurationProperties属性名灵活绑定

类中属性名一般会采用驼峰方式

 类中属性名一般会采用驼峰方式,配置参数名可以用如下方式:

prefix的值只可使用-、小写,如 @ConfigurationProperties(prefix = "acme.my-project.person")

 如果名字本身包含-_等特殊字符怎么办?用[]包裹:

 bean属性参数值绑定合法性校验@Validated

直接使用notnull 等等。

@ConfigurationProperties VS @Value

Profiles详解 

profile是 什么

  • Spring配置文件提供的一种隔离应用程序配置的方法,使其仅在特定环境中可用。
  • 可通过profile指定Bean的应用环境(如开发、测试、生产等环境)
  •  可通过profile指定不同环境的配置参数值
通过profile指定Bean的应用环境 任何@Component或@Configuration都可以用@Profile来标记,以便在加载时进行限制。

这样可以局部的去改变其参数

通过profile指定不同环境的配置参数值 方式一∶通过不同的环境配置文件来区分

         application-profile.properties或application-profile.yml

方式二:在同一个yml配置文件中区分 没有带-profile表示共用到所有环境、 还可通过spring.profiles.include来指定某个环 境包含的其他profile定义 指定程序启用的profiles
  •  通过配置参数spring.profiles.active来指定应用启用的profiles
      环境变量、jvm参数、命令行程序参数、application.properties中都可以
spring.profiles.active=dev,hsqldb 
- -spring.profiles.active=dev,hsqldb
  • 编程式指定启用的环境
SpringApplication.setAdditionalProfiles(...)
没有通过spring.profiles.active指定启用的profiles时,将使用-default的(如果有)   通过spring.config.location指定的配置文件不会应用profile,目录会。

AutoConfiguration

AutoConfiguration的加载触发 1、注解EnableAutoConfiguration 2、AutoConfigurationImportSelector 3、通对selectImports加载自动配置信息 4、通getCandidateConfigurations加载META-INF/spring.factories Spring官方集成自动配置

 Auto-configuration Classes (spring.io)

以上是关于Spring boot基本使用及 stater机制原理的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot Stater原理

玩转 Spring Boot 原理篇(自动装配前凑之自定义Stater)

【原创】Springboot Redis配置总结( 基于spring-boot-data-redis-stater )

SpringBoot 核心源码解读

SpringBoot Web项目依赖分析

Spring Boot (33) 分布式锁