SpringBoot知识概括

Spring Boot简介

Spring Boot 简介:

  • 简化Spring应用开发的一个框架;
  • 整个Spring技术栈的一个大整合;
  • J2EE开发的一站式解决方案;

微服务:

  • 微服务:架构风格(服务微化)
  • 一个应用应该是一组小型服务;可以通过HTTP的方式进行互通;
  • 对比:
    ①单体应用:ALL IN ONE
    ②微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元;

Spring Boot入门:

  • 一个功能:浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串;
  • 步骤:
    ①创建一个maven工程;(jar)
    ②导入spring boot相关的依赖
    ③编写一个主程序;启动Spring Boot应用
    ④编写相关的Controller、Service
    ⑤运行主程序测试
    ⑥简化部署:将这个应用打成jar包,直接使用java -jar的命令进行执行。
----------------------------------pom.xml jar包配置----------------------------------
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

----------------------------------springboot主程序----------------------------------
/**
 -  @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}
-------------------------Controller层-------------------------------------------
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }
}
----------------------------pom.xml 插件配置----------------------------------------
/**
 -  这个插件,可以将应用打包成一个可执行的jar包
 */
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

springboot研究:

  • POM文件中的plugin:
    ①Spring Boot的Maven插件(Spring Boot Maven plugin)能够以Maven的方式为应用提供Spring Boot的支持,即为Spring Boot应用提供了执行Maven操作的可能。
  • POM文件中的父项目:
    spring-boot-dependencies来真正管理Spring Boot应用里面的所有依赖版本:Spring Boot的版本仲裁中心。
    以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
----------------------------------pom.xml parent依赖----------------------------------
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>
-------------------pom.xml parent依赖的父项目是----------------------------

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
  • POM文件中的启动器:
    ①Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器)。
    ②只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
    其中spring-boot-starter-web依赖spring-boot-starter,spring-boot-starter是Spring Boot的核心启动器,包含了自动配置、日志和YAML。
    <1>当不使用web依赖时则会导入这个核心启动器依赖。
---spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件。
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

------Spring Boot的核心启动器依赖------
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
	<version>2.1.5.RELEASE</version>
	<scope>compile</scope>
</dependency>
  • 主程序类、主入口类:
    @SpringBootApplication:Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。
    @SpringBootConfiguration:Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类。
    @Configuration:配置类上来标注这个注解。
    <1>配置类等于配置文件,配置类也是容器中的一个组件@Component。
    @EnableAutoConfiguration:开启自动配置功能,以前我们需要配置的东西,Spring Boot帮我们自动配置。@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;
    @AutoConfigurationPackage:自动配置包
    @Import:给容器中导入一个组件
    <1>@Import(AutoConfigurationPackages.Registrar.class):Spring的底层注解@Import给容器中导入的组件为AutoConfigurationPackages.Registrar.class。
    1、将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
    <2>@Import(EnableAutoConfigurationImportSelector.class):给容器中导入组件。
    1、EnableAutoConfigurationImportSelector:将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。
----------------------------------主程序类----------------------------------
@SpringBootApplication
public class HelloWorldMainApplication {
    public static void main(String[] args) {
        // Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

-------------------------@SpringBootApplication注解----------------------------------
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
      @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

-------------------------@SpringBootConfiguration注解----------------------------------
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration { 
}

-------------------------@Configuration注解----------------------------------
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
}

-------------------------@EnableAutoConfiguration注解----------------------------------
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

-------------------------@AutoConfigurationPackage 注解----------------------------------
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
  • 总结:
    ①会给容器中导入非常多的自动配置类(xxxAutoConfiguration):就是给容器中导入这个场景需要的所有组件,并配置好这些组件。
    <1>有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。
    在这里插入图片描述
    ②SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
    <1>SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作,以前我们需要自己配置的东西,自动配置类都帮我们。
    J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar。

快速创建Spring Boot项目:

  • IDEA:使用 Spring Initializer快速创建项目
    ①IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目。
    ②选择我们需要的模块,向导会联网创建Spring Boot项目。
    ③默认生成的Spring Boot项目。
一、主程序已经生成好了,我们只需要我们自己的逻辑
二、resources文件夹中目录结构:
<1>static:保存所有的静态资源,如js,css,images。
<2>templates:保存所有的模板页面。(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面)
但是可以使用模板引擎(freemarker、thymeleaf)。
<3>application.properties:Spring Boot应用的配置文件,可以修改一些默认设置。
  • STS使用 Spring Starter Project快速创建项目

配置文件

配置文件:

  • SpringBoot使用一个全局的配置文件,配置文件名是固定的:
    application.properties
    application.yml
  • 配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好。
  • YAML(YAML Ain't Markup Language)两个解释:
    ①YAML A Markup Language:是一个标记语言
    ②YAML isn’t Markup Language:不是一个标记语言;
  • 标记语言:以前的配置文件;大多都使用的是 "xxxx.xml"文件,现在使用YAML,YAML,以数据为中心,比json、xml等更适合做配置文件。
    ①配置例子
-----yaml------
server:
  port: 8081
  
-----xml------
<server>
	<port>8081</port>
</server>

YAML语法:

  • 基本语法:k:(空格)v:表示一对键值对(空格必须有)
    ①以空格的缩进来控制层级关系,只要是左对齐的一列数据,都是同一个层级的。
    ②属性和值也是大小写敏感。
server:
    port: 8081
    path: /hello
  • 值的写法:
一、字面量:普通的值(数字,字符串,布尔)
k: v:字面直接来写。
<1>字符串默认不用加上单引号或者双引号。

"":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
name:   "zhangsan \n lisi":输出;zhangsan 换行  lisi

'':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
name:   ‘zhangsan \n lisi’:输出;zhangsan \n  lisi

总结:转义是将具体意思往反方向转换,例如转义字符本身表示换行,转义的话就是\n,不转义就是换行。

二、对象、Map(属性和值)(键值对):
k: v:在下一行来写对象的属性和值的关系,注意缩进。

对象还是k: v的方式
friends:
		lastName: zhangsan
		age: 20
		
行内写法:
friends: {lastName: zhangsan,age: 18}

三、数组(List、Set):

用- 值表示数组中的一个元素:
pets:
 - cat
 - dog
 - pig

行内写法:
pets: [cat,dog,pig]

配置文件值注入:

  • 配置文件:
person:
    lastName: hello
    age: 18
    boss: false
    birth: 2017/12/12
    maps: {
   k1: v1,k2: 12}
    lists:
      - lisi
      - zhaoliu
    dog:
      name: 小狗
      age: 12
  • javaBean:
    ①解释:将配置文件中配置的每一个属性的值映射到这个组件中
    @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。
    <1>prefix = “person”:配置文件中哪个下面的所有属性进行一一映射
    注意:只有这个组件是容器中的组件,才能用容器提供的@ConfigurationProperties功能。
    配置文件注入值数据校验使用Validated注解在类上面,使用@Email等等注解在字段上面。
    ⑤使用@ConfigurationProperties和@Bean注解在配置类的Bean定义方法上:将方法返回的对象定义为一个Bean,并使用配置文件中相应的属性初始化该Bean的属性。
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
	@Email
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
  • 导入配置文件处理器,以后编写配置就有提示了。
<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

在这里插入图片描述

@Value获取值和@ConfigurationProperties获取值比较:

  • 配置文件yml还是properties他们都能获取到值;
  • 如果我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
  • 如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@ConfigurationProperties @Value
功能 批量注入配置文件中的属性 一个个指定
松散绑定(松散语法) 支持 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 支持 不支持

@PropertySource、@ImportResource、@Bean:

  • @PropertySource:加载指定的配置文件。
    通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。
    通过@value({SPEL})里编写spel表达式从环境变量、配置文件获取值
@PropertySource(value = {"classpath:person.properties"})
@Component
public class Person {
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean boss;
  • @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效。
    ①Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别。
    ②想让Spring的配置文件生效加载进来,使用@ImportResource标注在一个配置类上。
//导入Spring的配置文件让其生效
@ImportResource(locations = {"classpath:beans.xml"})

//Spring的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="helloService" class="com.atguigu.springboot.service.HelloService"></bean>
</beans>
  • SpringBoot推荐给容器中添加组件的方式:推荐使用全注解的方式
    ①配置类@Configuration
    ②使用@Bean给容器中添加组件
/**
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 */
@Configuration
public class MyAppConfig {
    //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

配置文件占位符:

  • 随机数
  • 占位符获取之前配置的值,如果没有可以是用:指定默认值
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}

person.last-name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15

Profile:

  • 多Profile文件:
    ①我们在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml
    ②默认使用application.properties的配置;
    ③使用profile还有个明显的用处——可以抽取application.yml中的配置信息到其他文件。如当我们的项目越来越大时,项目配置信息太多,application.yml配置文件会比较大,这时我们可以通过定义profile,将一些配置信息从application.yml中抽取到一个单独的文件中,如建立:
    <1>application-devFtp.yml 只存放开发环境ftp相关的配置信息
    <2>application-devRedis.yml 只存放开发环境redis相关的配置信息
    <3>application-testFtp.yml 只存放测试环境ftp相关的配置信息
    <4>application-testRedis.yml 只存放测试环境redis相关的配置信息
    然后在application.yml中切换开发环境,配置spring.profiles.active=dev, devFtp,devRedis 来引入dev、devFtp、devRedis的配置即可。
    ⑤切换测试环境,配置spring.profiles.active=test, testFtp,testRedis 来引入test、testFtp、testRedis的配置即可。
    默认配置:如果没有指定profiles,则默认配置生效。
  • yml还支持多文档块方式:
    注意:文档块以---分隔
server:
  port: 8081
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev


---

server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境
  • 激活指定profile
    在配置文件中指定 spring.profiles.active=dev
    命令行:java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
    <1>可以直接在测试的时候,配置传入命令行参数
    虚拟机参数:-Dspring.profiles.active=dev
  • 总结:
    appliaction-dev.yml,appliaction-test.yml,appliaction-prd.yml等等环境这些配置文件在每个module中都需要,除了工具module除外。
    appliaction.yml一般放在web启动类的module中,再通过指定spring.profiles.active来整合多个文件。
    每个module的appliaction.yml最终会整合在一起。
    例如在appliaction.yml中指定spring.profiles.active为dev(本web模块的dev环境文件)、devFtp(Ftp模块的dev环境文件)、devRedis(Redis模块的dev环境文件)。
    ⑤链接:多模块配置文件问题
    使用maven的时候一个可运行的springboot项目中只能有一个application.properties。其他模块配置文件一定要以application-XX的形式命名,不然后续配置无法识别。若想以其他文件名或其他文件类型的话需要配置@PropertySource注解。
    ⑦多模块思路:写测试代码时要考虑测试代码是否是通用的,是的话写在web模块。

配置文件加载位置:

  • springboot启动会扫描以下位置的application.properties或者application.yml文件作为Spring
    boot的默认配置文件
    ①jar包同级目录下的/config目录–file:./config/
    ②jar包同级目录–file:./
    ③classpath里的/config目录–classpath:/config/
    ④classpath 同级目录–classpath:/
  • 优先级由高到底,高优先级的配置会覆盖低优先级的配置,SpringBoot会从这四个位置全部加载主配置文件,互补配置因此最终底层会互补成一个配置文件
  • 我们还可以通过spring.config.location来改变默认的配置文件位置
    ①项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置。
    <1>java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

外部配置加载顺序:

  • SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置。

  • 规则为:
    由jar包外向jar包内进行寻找
    优先加载带profile
    再来加载不带profile

  • 具体:
    ①命令行参数:所有的配置都可以在命令行上进行指定
    <1>java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/abc
    <2>多个配置用空格分开; --配置项=值
    ②来自java:comp/env的JNDI属性
    ③Java系统属性(System.getProperties())
    ④操作系统环境变量
    ⑤RandomValuePropertySource配置的random.*属性值
    jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
    jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
    jar包外部的application.properties或application.yml(不带spring.profile)配置文件
    jar包内部的application.properties或application.yml(不带spring.profile)配置文件
    ⑩@Configuration注解类上的@PropertySource
    ⑪通过SpringApplication.setDefaultProperties指定的默认属性

  • 所有支持的配置加载来源:参考官方文档

自动配置原理:

  • SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
  • @EnableAutoConfiguration 作用:
    利用EnableAutoConfigurationImportSelector给容器中导入一些组件。
    ②可以查看selectImports()方法的内容:
一、扫描
<1>@Import(AutoConfigurationPackages.Registrar.class):
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
<2>扫描所有jar包类路径下的META-INF/spring.factories文件,
把扫描到的这些文件的内容包装成properties对象

二、获取候选的配置
<1>List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)
<2>从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中
SpringFactoriesLoader.loadFactoryNames()
  • spring.factories 文件:
    ①每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用他们来做自动配置。
    每一个自动配置类进行自动配置功能。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
  • 以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释:
    ①根据当前不同的条件判断,决定这个配置类是否生效?
    <1>一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
    所有在配置文件中能配置的属性都是在xxxxProperties类中封装者中,配置文件能配置什么就可以参照某个功能对应的这个属性类。
//表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@Configuration   

//启动指定类的ConfigurationProperties功能;将配置文件中对应的值和
//HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@EnableConfigurationProperties(HttpEncodingProperties.class)  

//Spring底层@Conditional注解(Spring注解版),根据不同的条件,
//如果满足指定的条件,整个配置类里面的配置就会生效;
//判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication 

//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass(CharacterEncodingFilter.class)  

//判断配置文件中是否存在某个配置spring.http.encoding.enabled;如果不存在,判断也是成立的
@ConditionalOnProperty(prefix = "spring.http.encoding",
value = "enabled", matchIfMissing = true)  
 
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
   
  
  	//他已经和SpringBoot的配置文件映射了
  	private final HttpEncodingProperties properties;
  
   //只有一个有参构造器的情况下,参数的值就会从容器中拿
  	public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
   
		this.properties = properties;
	}
  
    @Bean   //给容器中添加一个组件,这个组件的某些值需要从properties中获取
	@ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件?
	public CharacterEncodingFilter characterEncodingFilter() {
   
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
		return filter;
	}
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http.encoding") 
public class HttpEncodingProperties {
   
   public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
   ...
}   
  • 精髓:
    ①SpringBoot启动会加载大量的自动配置类。
    ②我们看我们需要的功能有没有SpringBoot默认写好的自动配置类。
    ③我们再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件有,我们就不需要再来配置了)
    给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值。
    ⑤注意:
    <1>xxxxAutoConfigurartion:自动配置类,给容器中添加组件。
    <2>xxxxProperties:封装配置文件中相关属性。

@Conditional派生注解(Spring注解版原生的@Conditional作用):

  • 作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效。
@Conditional扩展注解 作用(判断是否满足当前指定条件)
@ConditionalOnJava 系统的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean
@ConditionalOnMissingBean 容器中不存在指定Bean
@ConditionalOnExpression 满足SpEL表达式指定
@ConditionalOnClass 系统中有指定的类
@ConditionalOnMissingClass 系统中没有指定的类
@ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty 系统中指定的属性是否有指定的值
@ConditionalOnResource 类路径下是否存在指定资源文件
@ConditionalOnWebApplication 当前是web环境
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项
  • 自动配置类必须在一定的条件下才能生效,我们怎么知道哪些自动配置类生效?
    我们可以通过启用debug=true属性,来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效。
=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:(自动配置类启用的)
-----------------

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
        
    
Negative matches:(没有启动,没有匹配成功的自动配置类)
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

   AopAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)
        

日志

日志框架:

  • 开发一个大型系统:
    ①System.out.println(“”);将关键数据打印在控制台;去掉?写在一个文件?
    ②框架来记录系统的一些运行时信息;日志框架 ; zhanglogging.jar;
    ③高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar?
    ④将以前框架卸下来?换上新的框架,重新修改之前相关的API;zhanglogging-prefect.jar;
    ⑤JDBC—数据库驱动;​
  • 办法:
    ①写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;
    ②给项目中导入具体的日志实现就行了;我们之前的日志框架都是实现的抽象层;

市面上的日志框架;

  • JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j…
    ①左边选一个门面(抽象层)、右边来选一个实现。
日志门面 (日志的抽象层) 日志实现
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-logging Log4j JUL(java.util.logging) Log4j2 Logback
  • SpringBoot:底层是Spring框架,Spring框架默认是用JCL。
  • SpringBoot选用:
    日志门面: SLF4J
    日志实现:Logback

如何在系统中使用SLF4j:

  • 以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法。

  • 给系统里面导入slf4j的jar和 logback的实现jar

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
   
  public static void main(String[] args) {
   
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}
  • 每一个日志的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件
    ①图示:
    在这里插入图片描述

遗留问题:

  • (slf4j+logback):Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、xxxx
  • 统一日志记录,如何让系统中所有的日志都统一到slf4j:
    将系统中其他日志框架先排除出去。
    用中间包来替换原有的日志框架。
    我们导入slf4j其他的实现。
    在这里插入图片描述

SpringBoot日志关系:`

  • SpringBoot依赖spring-boot-starter,spring-boot-starter依赖spring-boot-starter-logging,并使用它来做日志功能。
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
  • 底层依赖关系:
    在这里插入图片描述
  • 总结:
    ①SpringBoot底层也是使用slf4j+logback的方式进行日志记录
    ②SpringBoot也把其他的日志都替换成了slf4j;
    中间替换包,例如jul-to-slf4j。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zoitwLGh-1597995719925)(images/搜狗截图20180131221411.png)]
    SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的默认日志框架排除掉即可。
    <1>Spring框架用的是commons-logging,如下:
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

springBoot日志使用:

  • SpringBoot默认帮我们配置好了日志。
	//记录器
	Logger logger = LoggerFactory.getLogger(getClass());
	@Test
	public void contextLoads() {
   
		//System.out.println();

		//日志的级别;
		//由低到高   trace<debug<info<warn<error
		//可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效
		logger.trace("这是trace日志...");
		logger.debug("这是debug日志...");
		//SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root级别
		logger.info("这是info日志...");
		logger.warn("这是warn日志...");
		logger.error("这是error日志...");


	}
日志输出格式:
	%d表示日期时间,
	%thread表示线程名,
	%-5level:级别从左显示5个字符宽度
	%logger{50} 表示logger名字最长50个字符,否则按照句点分割。 
	%msg:日志消息,
	%n是换行符

总结:%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
  • SpringBoot修改日志的默认配置:
# 自定义logger
logging.level.com.atguigu=trace

# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=G:/springboot.log

# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
logging.path=/spring/log

#  在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n

# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
logging.file logging.path Example Description
(none) (none) 只在控制台输出
指定文件名 (none) my.log 输出日志到my.log文件
(none) 指定目录 /var/log 输出到指定目录的 spring.log 文件中
  • 指定配置:给类路径下放上每个日志框架自己的配置文件即可,SpringBoot就不使用他默认配置的了。
    ①logback.xml:直接就被日志框架识别了。
    ②logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能。
    <1>如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误: no applicable action for [springProfile]
Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties
<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
  	可以指定某段配置只在某个环境下生效
</springProfile>

例如:
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <springProfile name="dev">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
        </springProfile>
        <springProfile name="!dev">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
        </springProfile>
    </layout>
</appender>

切换日志框架:

  • 可以按照slf4j的日志适配图,进行相关的切换。
  • 例如:slf4j+log4j的方式。
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  //排除底层的log4j替换到slf4j框架以及logback实现框架
  <exclusions>
    <exclusion>
      <artifactId>logback-classic</artifactId>
      <groupId>ch.qos.logback</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j-over-slf4j</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>
//加入log4j-slf4j绑定jar包及log4j实现jar包
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

  • 例如:slf4j+log4j2的方式。
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  //直接去掉starter-logging配置器
  <exclusions>
     <exclusion>
       <artifactId>spring-boot-starter-logging</artifactId>
       <groupId>org.springframework.boot</groupId>
     </exclusion>
  </exclusions>
</dependency>
//使用starter-log4j2配置器
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Web开发

Web开发简介:

  • 使用SpringBoot
  • 创建SpringBoot应用,选中我们需要的模块
  • SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来
  • 自己编写业务代码

springboot的jar包目录结构分析:

  • SpringBoot提供的bootstrap的类是放到包的最外面,比如上面的org.springframework.boot.loader。
  • 应用程序的代码则是需要放到BOOT-INF/classes目录下面;然后应用程序依赖的其他的jar包文件需要放到BOOT-INF/lib目录下。
  • 当这个jar作为standardalone的程序运行时(没有放到container),SpringBoot会在生成的META-INF/MANIFEST.MF里面将Main-Class设置成org.springframework.boot.loader.JarLauncher,JarLauncher类会创建一个spring自己的ClassLoader:LaunchedURLClassLoader, 这个classloader
    会就能通过URL来加载上面BOOT-INF/lib里面所依赖的包,并且通过反射Manifest里面的Start-Class里面定义的类,然后invoke这个类里面的main方法。
example.jar
 |
 +-META-INF
 |  +-MANIFEST.MF
 +-org
 |  +-springframework
 |     +-boot
 |        +-loader
 |           +-<spring boot loader classes>
 +-BOOT-INF
    +-classes
    |  +-mycompany
    |     +-project
    |        +-YourClasses.class
    +-lib
       +-dependency1.jar
       +-dependency2.jar

静态资源

SpringBoot对静态资源的映射规则:

  • 所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源。
    ①webjars:以jar包的方式引入静态资源;
    ②localhost:8080/webjars/jquery/3.3.1/jquery.js
    在这里插入图片描述
  • "/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射
    ①localhost:8080/abc === 去静态资源文件夹里面找abc
  • 欢迎页; 静态资源文件夹下的所有index.html页面;被"/**"映射
    ①localhost:8080/ 找index页面
  • 所有的 **/favicon.ico 都是在静态资源文件下找;
------------------------------静态资源配置类------------------------
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
   
  		//可以设置和静态资源有关的参数,缓存时间等

		@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
   
			if (!this.resourceProperties.isAddMappings()) {
   
				logger.debug("Default resource handling disabled");
				return;
			}
			Integer cachePeriod = this.resourceProperties.getCachePeriod();
			if (!registry.hasMappingForPattern("/webjars/**")) {
   
				customizeResourceHandlerRegistration(
						registry.addResourceHandler("/webjars/**")
								.addResourceLocations(
										"classpath:/META-INF/resources/webjars/")
						.setCachePeriod(cachePeriod));
			}
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
          	//静态资源文件夹映射
			if (!registry.hasMappingForPattern(staticPathPattern)) {
   
				customizeResourceHandlerRegistration(
						registry.addResourceHandler(staticPathPattern)
								.addResourceLocations(
										this.resourceProperties.getStaticLocations())
						.setCachePeriod(cachePeriod));
			}
		}

        //配置欢迎页映射
		@Bean
		public WelcomePageHandlerMapping welcomePageHandlerMapping(
				ResourceProperties resourceProperties) {
   
			return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
					this.mvcProperties.getStaticPathPattern());
		}

       //配置喜欢的图标
		@Configuration
		@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
		public static class FaviconConfiguration {
   

			private final ResourceProperties resourceProperties;

			public FaviconConfiguration(ResourceProperties resourceProperties) {
   
				this.resourceProperties = resourceProperties;
			}

			@Bean
			public SimpleUrlHandlerMapping faviconHandlerMapping() {
   
				SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
				mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
              	//所有  **/favicon.ico 
				mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
						faviconRequestHandler()));
				return mapping;
			}

			@Bean
			public ResourceHttpRequestHandler faviconRequestHandler() {
   
				ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
				requestHandler
						.setLocations(this.resourceProperties.getFaviconLocations());
				return requestHandler;
			}

		}
		
------------------------------jquery-webjar------------------------
<!--引入jquery-webjar-->在访问的时候只需要写webjars下面资源的名称即可
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>jquery</artifactId>
			<version>3.3.1</version>
		</dependency>

------------------------------静态资源映射------------------------
"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":当前项目的根路径

模版引擎

模板引擎:

  • JSP、Velocity、Freemarker、Thymeleaf

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BHA11ORR-1597995719931)(images/template-engine.png)]

  • SpringBoot推荐的Thymeleaf,语法更简单,功能更强大。

thymeleaf的使用:

  • 引入thymeleaf
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
          	2.1.6
		</dependency>
切换thymeleaf版本
<properties>
		<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
		<!-- 布局功能的支持程序  thymeleaf3主程序  layout2以上版本 -->
		<!-- thymeleaf2   layout1-->
		<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
  </properties>
  • Thymeleaf自动配置类
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
   

	private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

	private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

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

	public static final String DEFAULT_SUFFIX = ".html";
  • 使用方法:只要我们把HTML页面放在classpath:/templates/,thymeleaf就能自动渲染。
  • 具体使用:
    ①导入thymeleaf的名称空间
    ②使用thymeleaf语法
----------------------名称空间-----------------
<html lang="en" xmlns:th="http://www.thymeleaf.org">

----------------------具体语法-----------------
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>成功!</h1>
    <!--th:text 将div里面的文本内容设置为 -->
    <div th:text="${hello}">这是显示欢迎信息</div>
</body>
</html>

thymeleaf语法规则:

  • th:text:改变当前元素里面的文本内容。
  • th:任意html属性,来替换原生属性的值。
    在这里插入图片描述
  • 表达式:
Simple expressions:(表达式语法)
    Variable Expressions: ${...}:获取变量值;OGNL;
    		1)、获取对象的属性、调用方法
    		2)、使用内置的基本对象:
    			#ctx : the context object.
    			#vars: the context variables.
                #locale : the context locale.
                #request : (only in Web Contexts) the HttpServletRequest object.
                #response : (only in Web Contexts) the HttpServletResponse object.
                #session : (only in Web Contexts) the HttpSession object.
                #servletContext : (only in Web Contexts) the ServletContext object.
                
                ${session.foo}
            3)、内置的一些工具对象:
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).

    Selection Variable Expressions: *{...}:选择表达式:和${}在功能上是一样;
    	补充:配合 th:object="${session.user}:
   <div th:object="${session.user}">
    <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
    <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
    <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
    </div>
    
    Message Expressions: #{...}:获取国际化内容
    Link URL Expressions: @{...}:定义URL;
    		@{/order/process(execId=${execId},execType='FAST')}
    Fragment Expressions: ~{...}:片段引用表达式
    		<div th:insert="~{commons :: main}">...</div>
    		
Literals(字面量)
      Text literals: 'one text' , 'Another one!' ,…
      Number literals: 0 , 34 , 3.0 , 12.3 ,…
      Boolean literals: true , false
      Null literal: null
      Literal tokens: one , sometext , main ,…
Text operations:(文本操作)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
Arithmetic operations:(数学运算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
Boolean operations:(布尔运算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
Comparisons and equality:(比较运算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
Conditional operators:条件运算(三元运算符)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
Special tokens:
    No-Operation: _ 

SpringBoot应用配置常用相关视图解析器:

  • SpringBoot使用JSP:SpringBoot在自动装配的时候默认就已经将JSP的视图解析器InternalResourceViewResolver装配。所以我们只需要进行配置使用即可。
-----------------------外置tomcat模式------------
第一步:创建自定义webapp目录

第二步:将此文件夹配置成项目的WEB模块

第三步:导入JSP相关依赖
<!-- 部署tomcat,排除冲突-->
<!-- 也可以在spring-boot-starter-web中使用exclusion排除这个依赖-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
   <scope>provided</scope>
</dependency>
<!-- servlet依赖 -->
<dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId> 
   <scope>provided</scope>
</dependency>
<dependency>
   <
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SpringBoot知识库系统是基于SpringBoot和MyBatis实现的一个系统,它采用了Docker容器化部署。该系统设计了6个不同的角色,可以实现电信知识的存储和管理。[2] 在SpringBoot项目中,可以使用两种不同格式的配置文件来配置系统。一种是Properties文件,另一种是YML文件。默认情况下,Spring Boot会使用application.properties作为系统配置文件,并将其放置在resources目录下。在这个配置文件中,我们可以设置系统的全局配置,例如端口号、数据库连接、日志、启动图案等。除了application.properties,Spring Boot还会读取其他指定位置的配置文件,包括项目根目录下的config目录、classpath下的config目录以及classpath目录。这样,我们可以根据不同的需求和场景来灵活配置系统。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Spring Boot+Vue3前后端分离实战wiki知识库系统之Spring Boot项目搭建](https://blog.csdn.net/Lbsssss/article/details/127600804)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【Springboot项目】电信知识库系统](https://blog.csdn.net/weixin_48180029/article/details/123241071)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值