Spring Boot 2 入门基础

学习要求
● 熟悉Spring基础
● 熟悉Maven使用

环境要求
● Java8及以上
● Maven 3.3及以上:https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started-system-requirements

学习资料
● 文档地址: https://www.yuque.com/atguigu/springboot
○ 文档不支持旧版本IE、Edge浏览器,请使用chrome或者firefox
● 视频地址: http://www.gulixueyuan.com/ https://www.bilibili.com/video/BV19K4y1L7MT?p=1
● 源码地址:https://gitee.com/leifengyang/springboot2

01、Spring与SpringBoot

1、Spring能做什么

1.1、Spring的能力

在这里插入图片描述

1.2、Spring的生态

https://spring.io/projects/spring-boot

覆盖了:
web开发
数据访问
安全控制
分布式
消息服务
移动开发
批处理

1.3、Spring5重大升级

1.3.1、响应式编程

在这里插入图片描述

1.3.2、内部源码设计

基于Java8的一些新特性,如:接口默认实现。重新设计源码架构。

2、为什么用SpringBoot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".
能快速创建出生产级别的Spring应用

2.1、SpringBoot优点

Create stand-alone Spring applications
创建独立Spring应用
Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
内嵌web服务器
Provide opinionated 'starter' dependencies to simplify your build configuration
自动starter依赖,简化构建配置
Automatically configure Spring and 3rd party libraries whenever possible
自动配置Spring以及第三方功能
Provide production-ready features such as metrics, health checks, and externalized configuration
提供生产级别的监控、健康检查及外部化配置
Absolutely no code generation and no requirement for XML configuration
无代码生成、无需编写XML
SpringBoot是整合Spring技术栈的一站式框架
SpringBoot是简化Spring技术栈的快速开发脚手架

2.2、SpringBoot缺点

人称版本帝,迭代快,需要时刻关注变化
封装太深,内部原理复杂,不容易精通

3、时代背景

3.1、微服务

James Lewis and Martin Fowler (2014)  提出微服务完整概念。
https://martinfowler.com/microservices/
In short, the microservice architectural style is an approach to developing a single application 
as a suite of small services, each running in its own process and communicating with lightweight mechanisms, 
often an HTTP resource API. These services are built around business capabilities and independently deployable 
by fully automated deployment machinery. 
There is a bare minimum of centralized management of these services, which may be written in different 
programming languages and use different data storage technologies.-- James Lewis and Martin Fowler (2014)
微服务是一种架构风格
一个应用拆分为一组小型服务
每个服务运行在自己的进程内,也就是可独立部署和升级
服务之间使用轻量级HTTP交互
服务围绕业务功能拆分
可以由全自动部署机制独立部署
去中心化,服务自治。服务可以使用不同的语言、不同的存储技术

3.2、分布式

在这里插入图片描述

分布式的困难

  • 远程调用
  • 服务发现
  • 负载均衡
  • 服务容错
  • 配置管理
  • 服务监控
  • 链路追踪
  • 日志管理
  • 任务调度

分布式的解决

  • SpringBoot + SpringCloud

3.3、云原生

原生应用如何上云。 Cloud Native

上云的困难

  • 服务自愈
  • 弹性伸缩
  • 服务隔离
  • 自动化部署
  • 灰度发布
  • 流量治理

上云的解决
在这里插入图片描述

4、如何学习SpringBoot

4.1、官网文档架构

查看版本新特性;
https://github.com/spring-projects/spring-boot/wiki#release-notes

02、SpringBoot2入门

1、Maven设置

<mirrors>
      <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      </mirror>
  </mirrors>
 
  <profiles>
         <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>
  </profiles>

2、需求:浏览器发送/hello请求,响应Hello,Spring Boot 2!

2.1、创建Maven工程

在这里插入图片描述

2.2、 引入依赖

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId> <!--spring boot 框架-->
	<version>2.3.4.RELEASE</version>
</parent>


	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId> <!--web服务的依赖,会导入Tomcat等一些列的库-->
		</dependency>
	</dependencies>

2.3、串讲主程序

package com.atguigu.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 主程序
 * @SpringBootApplication:这是一个SpringBoot应用
 */
@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);

    }
}

2.4、编写业务代码

package com.atguigu.boot.Controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

//@ResponseBody
//@Controller

@RestController
public class HelloControaller {

    @RequestMapping("/hello")
    public String handle01() {
        return "Hello,Spring Boot 2!";
    }
}

2.5、测试

直接运行main方法,然后在浏览器发起请求,浏览器应显示“Hello,Spring Boot 2!”。
在这里插入图片描述
在这里插入图片描述

2.6、简化配置

配置文件由application.properties统一管理

server.port=8888

2.7、简化部署

以往我们在部署web应用时,会将项目打成war包,再部署到服务器上,现在可以直接将项目打成可以执行的jar包,直接在服务器执行即可。

 <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

在这里插入图片描述
在这里插入图片描述

03、自动装配及原理

1、SpringBoot的特点

1.1、依赖管理

  • 父项目做依赖管理
<!--一般父项目都是用来做依赖管理的-->
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.3.4.RELEASE</version>
</parent>

<!--spring-boot-starter-parent-->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-dependencies</artifactId>
		<version>2.3.4.RELEASE</version>
	</parent>

<!--spring-boot-dependencies中几乎声明了所有开发中常用的依赖的版本号,这种机制称为自动版本仲裁机制-->
  • 导入starter场景启动器
<!--
1、见到很多 spring-boot-starter-* : *就某种场景
2、只要引入starter,这个场景的所有常规需要的依赖我们都自动引入
3、SpringBoot所有支持的场景
https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter
4、见到的  *-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
5、所有场景启动器最底层的依赖为spring-boot-starter
-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
  <version>2.3.4.RELEASE</version>
  <scope>compile</scope>
</dependency>
  • 版本冲裁及版本管理

<!--
1、引入依赖默认都可以不写版本
2、引入非版本仲裁的jar,要写版本号。
查看spring-boot-dependencies里面规定当前依赖的版本用的key。
在当前项目里面重写配置。
-->
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

1.2、自动配置

  • 自动配好Tomcat
    • 引入Tomcat依赖。
    • 配置Tomcat
  • 自动配好SpringMVC
    • 引入SpringMVC全套组件
    • 自动配好SpringMVC常用组件(功能)
  • 自动配好Web常见功能,如:字符编码问题
    • SpringBoot帮我们配置好了所有web开发的常见场景
  • 默认的包结构
    • 主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来
    • 无需以前的包扫描配置
    • 想要改变扫描路径,@SpringBootApplication(scanBasePackages=“com.atguigu”)
      • 或者@ComponentScan 指定扫描路径
        @SpringBootApplication
        等同于
        @SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan("com.atguigu.boot")
        
  • 各种配置拥有默认值
    • 默认配置最终都是映射到某个类上,如:MultipartProperties
    • 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
  • 按需加载所有自动配置项
    • 非常多的starter
    • 引入了哪些场景这个场景的自动配置才会开启
    • SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

2、容器功能

2.1、组件添加

  • @Configuration
    基本使用

    • Full模式,配置类组件之间有依赖关系,方法会被调用得到之前的单实力组件。
    • Lite模式,配置类组件之间无依赖关系,用Lite模式加速器启动过程,减少判断。
    //#############################Configuration使用示例######################################################
    /**
     * 1、配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的
     * 2、配置类本身也是组件
     * 3、proxyBeanMethods:代理bean的方法
     *      Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
     *      Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
     *      组件依赖必须使用Full模式默认。其他默认是否Lite模式
     *
     *
     *
     */
    @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
    public class MyConfig {
    
        /**
         * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
         * @return
         */
        @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
        public User user01(){
            User zhangsan = new User("zhangsan", 18);
            //user组件依赖了Pet组件
            zhangsan.setPet(tomcatPet());
            return zhangsan;
        }
    
        @Bean("tom")
        public Pet tomcatPet(){
            return new Pet("tomcat");
        }
    }
    
    
    //################################@Configuration测试代码如下########################################
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan("com.atguigu.boot")
    public class MainApplication {
    
        public static void main(String[] args) {
            //1、返回我们IOC容器
            ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
    
            //2、查看容器里面的组件
            String[] names = run.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
    
            //3、从容器中获取组件
    
            Pet tom01 = run.getBean("tom", Pet.class);
    
            Pet tom02 = run.getBean("tom", Pet.class);
    
            System.out.println("组件:"+(tom01 == tom02));
    
    
            //4、com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
            MyConfig bean = run.getBean(MyConfig.class);
            System.out.println(bean);
    
            //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
            //保持组件单实例
            User user = bean.user01();
            User user1 = bean.user01();
            System.out.println(user == user1);
    
    
            User user01 = run.getBean("user01", User.class);
            Pet tom = run.getBean("tom", Pet.class);
    
            System.out.println("用户的宠物:"+(user01.getPet() == tom));
    
        }
    }
    
  • @Bean-用于将一个方法标记为Spring容器中的一个Bean。具体来说,@Bean注解可以用于方法上,该方法返回一个对象,该对象将被Spring容器管理和提供给其他程序组件使用,让IOC容器知道这个组件存在。(相当于创建对象);@Component-注解表明一个类会作为组件类,并告知Spring要为这个类创建bean,使用 @Component注解在一个类上,表示将此类标记为Spring容器中的一个Bean。(相当于创建对象)、@Controller-代表是一个控制器;@Service-代表是一个业务逻辑组件;@Repository-代表是一个数据库层组件

  • @ComponentScan-包扫描、@Import-为容器添加组件

    /*
     * 4、@Import({User.class, DBHelper.class})
     *      给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
     *
     *
     *
     */
    
    @Import({User.class, DBHelper.class})
    @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
    public class MyConfig {
    }
    

    @Import 高级用法: https://www.bilibili.com/video/BV1gW411W7wy?p=8
    注解的解释及用法:http://t.csdnimg.cn/ASzxy

  • @Conditional-条件装配:满足Conditional指定的条件,则进行组件注入
    在这里插入图片描述

    //=====================测试条件装配==========================
    @Configuration(proxyBeanMethods = false) //告诉SpringBoot这是一个配置类 == 配置文件
    //@ConditionalOnBean(name = "tom") //当容器中有组件tom组件时,则生成对应组件(myconfig、user01、tom22)
    @ConditionalOnMissingBean(name = "tom") //当容器中没有tmo组件时,则生成对应组件(myconfig、user01、tom22)
    // 组件的位置决定了会生成哪些组件,如果@ConditionalOnMissingBean位置在tomcatPet方法上,则只生成tom22
    public class MyConfig {
    
    
        /**
         * Full:外部无论对配置类中的这个组件注册方法调用多少次获取的都是之前注册容器中的单实例对象
         * @return
         */
    
        @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例
        public User user01(){
            User zhangsan = new User("zhangsan", 18);
            //user组件依赖了Pet组件
            zhangsan.setPet(tomcatPet());
            return zhangsan;
        }
    
        @Bean("tom22")
        public Pet tomcatPet(){
            return new Pet("tomcat");
        }
    }
    
    public static void main(String[] args) {
            //1、返回我们IOC容器
            ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
    
            //2、查看容器里面的组件
            String[] names = run.getBeanDefinitionNames();
            for (String name : names) {
                System.out.println(name);
            }
    
            boolean tom = run.containsBean("tom");
            System.out.println("容器中Tom组件:"+tom);
    
            boolean user01 = run.containsBean("user01");
            System.out.println("容器中user01组件:"+user01);
    
            boolean tom22 = run.containsBean("tom22");
            System.out.println("容器中tom22组件:"+tom22);
    
    
        }
    

2.2、 原生配置文件引入

  • @ImportResource 导入资源文件中配置的组件
    <!--======================beans.xml=========================-->
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    
        <bean id="haha" class="com.atguigu.boot.bean.User">
            <property name="name" value="zhangsan"></property>
            <property name="age" value="18"></property>
        </bean>
    
        <bean id="hehe" class="com.atguigu.boot.bean.Pet">
            <property name="name" value="tomcat"></property>
        </bean>
    </beans>
    
    @ImportResource("classpath:beans.xml")
    public class MyConfig {}
    
    //======================测试=================
            boolean haha = run.containsBean("haha");
            boolean hehe = run.containsBean("hehe");
            System.out.println("haha:"+haha);//true
            System.out.println("hehe:"+hehe);//true
    

2.3、配置绑定

  • 使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;
    例子:

    public class getProperties {
         public static void main(String[] args) throws FileNotFoundException, IOException {
             Properties pps = new Properties();
             pps.load(new FileInputStream("a.properties"));
             Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
             while(enum1.hasMoreElements()) {
                 String strKey = (String) enum1.nextElement();
                 String strValue = pps.getProperty(strKey);
                 System.out.println(strKey + "=" + strValue);
                 //封装到JavaBean。
             }
         }
     }
    
  • @Component + @ConfigurationProperties

    /**
     * 只有在容器中的组件,才会拥有SpringBoot提供的强大功能
     */
    @Component
    @ConfigurationProperties(prefix = "mycar")
    public class Car {
    
        private String brand;
        private Integer price;
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public void setPrice(Integer price) {
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Car{" +
                    "brand='" + brand + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
    @RestController
    public class Hello {
    
        @Autowired
        Car car;
    
        @RequestMapping("/car")
        public Car car() {
            return car;
        }
        @RequestMapping("/hello")
        public String handle01() {
    
            return "Hello,Spring boot 2!";
        }
    }
    

    application.properties

    mycar.brand=BYD
    mycar.price=100000
    

    在这里插入图片描述

    使用@Component注解,将组件注册到容器中,使用@ConfigurationProperties(prefix = “mycar”)注解,读取application.properties以mycar开头的配置项

  • @EnableConfigurationProperties + @ConfigurationProperties

    package com.atguigu.boot.bean;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    //@Component
    @ConfigurationProperties(prefix = "mycar")
    public class Car {
        private String brand;
        private Integer price;
    
        public Car() {
        }
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    
        public Integer getPrice() {
            return price;
        }
    
        public void setPrice(Integer price) {
            this.price = price;
        }
    
        public Car(String brand, Integer price) {
            this.brand = brand;
            this.price = price;
        }
    
        @Override
        public String toString() {
            return "Car{" +
                    "brand='" + brand + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    
    package com.atguigu.boot.config;
    
    import com.atguigu.boot.bean.Car;
    import com.atguigu.boot.bean.Pet;
    import com.atguigu.boot.bean.User;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @ConditionalOnMissingBean(name = "tmo")
    @Configuration(proxyBeanMethods = false)
    @EnableConfigurationProperties(Car.class)
    public class Myconfig {
    
        @Bean(name = "UserZS")
        public User user00() {
    
            return new User("zhangsan",5,new Pet("tom"));
        }
    
        @Bean(name = "TomCat")
        public Pet pet00() {
    
            return new Pet("tom");
        }
    
        @Bean
        public Pet Pet01() {
    
            return new Pet("jerry");
        }
    }
    

    在这里插入图片描述

    如果要注入的JavaBean是第三方或者无法添加注解@Component,则可以在控制类中使用@EnableConfigurationProperties注解来实现配置绑定

3、自动配置原理入门

3.1、引导加载自动配置类

@SpringBootApplication注解相当于下面三个注解的集合

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}    
  • @SpringBootConfiguration
    @Configuration。代表当前是一个配置类
  • @ComponentScan
    指定扫描哪些,Spring注解;
  • @EnableAutoConfiguration
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {}
    
    • @AutoConfigurationPackage
      自动配置包?指定了默认的包规则

      @Import(AutoConfigurationPackages.Registrar.class)  //给容器中导入一个组件
      public @interface AutoConfigurationPackage {}
      
      //利用Registrar给容器中导入一系列组件
      //将指定的一个包下的所有组件导入进来?MainApplication 所在包下。
      

      在这里插入图片描述
      在这里插入图片描述

    • @Import(AutoConfigurationImportSelector.class)

      1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
      2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
      3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
      4、从META-INF/spring.factories位置来加载一个文件。
      	默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
          spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
      

      在这里插入图片描述

C:\Users\Untifa.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.6.10\spring-boot-autoconfigure-2.6.10.jar!\META-INF\spring.factories 文件里列出了spring-boot一启动就要加载到容器中的所有类,一共133个类,与debug时的数量一致

# 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.webservices.client.WebServiceTemplateAutoConfiguration

3.2、按需开启自动配置项

虽然我们133个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。

3.3、修改默认配置

@Bean
@ConditionalOnBean(MultipartResolver.class)  //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
          //给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
          //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
	// Detect if the user has created a MultipartResolver but named it incorrectly
	return resolver;
}
//给容器中加入了文件上传解析器;

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先
在这里插入图片描述

@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
   }

总结:

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration
  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定
  • 生效的配置类就会给容器中装配很多组件
  • 只要容器中有这些组件,相当于这些功能就有了
  • 定制化配置
    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面取值 ----> application.properties

3.4、最佳实践

  • 引入场景依赖
    • https://docs.spring.io/spring-boot/reference/using/build-systems.html
  • 查看自动配置了哪些(选做)
    • 自己分析,引入场景对应的自动配置一般都生效了
    • 配置文件中debug=true开启自动配置报告。Negative(不生效)\Positive(生效)
  • 是否需要修改
    • 参照文档修改配置项
      https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#common-application-properties
      自己分析。xxxxProperties绑定了配置文件的哪些。
    • 自定义加入或者替换组件
      @Bean、@Component。。。
      自定义器 XXXXXCustomizer;

4、开发小技巧

4.1、Lombok

简化JavaBean开发

<!--1.首先引入依赖-->
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
	</dependency>
<!--2.idea中搜索安装lombok插件并安装 -->

在这里插入图片描述

package com.atguigu.boot.bean;

import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;

//@Component
@Data // 生成getter、setter方法
@ToString // 生成ToString方法
@AllArgsConstructor // 生成全参构造方法
@NoArgsConstructor // 生成无参构造方法
@EqualsAndHashCode // 生成hash值和equal方法
@Slf4j // 注入日志
@ConfigurationProperties(prefix = "mycar")
public class Car {
    private String brand;
    private Integer price;
}

4.2、dev-tools

	<dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-devtools</artifactId>
	    <optional>true</optional>
	</dependency>

Ctrl+F9来重新编译项目

4.3、Spring Initailizr(项目初始化向导)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

剞劂application.properties文件中文乱码问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/660001.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

松下MINAS A6B系列旋转电机规格书--A系列

一、松下电机型号的识别方法 二、松下标准型电机型号大全 三、松下电机的规格 四、电机外观 五、XA&#xff0c;XB连接器 六、USB连接器 七、EtherCAT用连接器X2A、X2B 八、IO连接器X4 输入输出信号接口 九、编码器连接器 十、模拟监视器用连接器X7 十一、电源连接器以及端子台…

python-web框架应用程序-Django环境搭建

python-web应用程序-Django环境搭建 一、Django入门 使用Django&#xff08;http://djangoproject.com/&#xff09;来开发一个名为“学习笔记”&#xff08;Learning Log&#xff09;的项目&#xff0c;这是一个在线日志系统&#xff0c;让你能够记录所学习的有关特定主题的知…

DiskCatalogMaker for Mac:您的磁盘目录管理专家

对于需要管理大量磁盘文件的用户来说&#xff0c;DiskCatalogMaker for Mac无疑是一款不可或缺的工具。这款专为Mac用户设计的磁盘目录制作软件&#xff0c;以其简洁的操作界面和强大的功能&#xff0c;帮助您轻松创建和管理磁盘目录。 DiskCatalogMaker支持多种磁盘格式&…

CSS学习笔记之高级教程(一)

1、圆角&#xff1a;border-radius border-radius 属性可以接受一到四个值。规则如下&#xff1a; 四个值 - border-radius: 15px 50px 30px 5px;&#xff08;依次分别用于&#xff1a;左上角、右上角、右下角、左下角&#xff09; 三个值 - border-radius: 15px 50px 30px;&a…

简介有限面积和无限周长

前言 分形理论是一种非常重要的科学概念,它被广泛应用于物理学、数学、生物学等领域。分形理论描述了一种重复自相似的结构,这种结构在不同的尺度上都具有类似的形态。由于分形理论的应用广泛且深远,了解分形理论可以帮助人们更好地理解自然界和人造世界中的现象。 作为一…

增强团队建设和创造力的 6 个敏捷游戏

加入敏捷框架提供了对资源的访问和支持&#xff0c;可以帮助你的组织最大限度地发挥敏捷的优势。它还提供了一个与其他敏捷从业者联系的平台&#xff0c;以共享最佳实践并相互学习。 实践敏捷工作方法可以让团队按照自己的节奏&#xff0c;尽可能多地发挥创造力来追求目标&…

网易狼人杀 设置点击自动发言

我们玩网易狼人杀 刚开始 都会发现 要按住麦克风才能发言 不得不说 相当的麻烦 我们可以点击如下图 右上角这个设置的齿轮 新弹出的设置面板上 勾选这个点击发言 然后 我们只需要 点一下 就可以进入发言状态 然后 再点一下即可停止发言 会方便非常多

游泳时用什么耳机听歌好?精品榜前四游泳耳机揭秘,款款佳品!

游泳时用什么耳机听歌好&#xff1f;这无疑是众多水上运动爱好者的共同疑问。在享受游泳带来的清凉与畅快时&#xff0c;若能伴随着悦耳的音乐&#xff0c;无疑能让整个体验更加完美。然而&#xff0c;市面上的游泳耳机种类繁多&#xff0c;品质各异&#xff0c;如何选择一款既…

网盘拉新项目,一单6.1,分享就能赚钱,人人可做!

前言 有几个圈友在问我&#xff0c;2024年有没有好的副业变现项目&#xff0c;我盘点近期比较热门的项目&#xff0c;比如红包封面、公众号爆文、视频号分成计划、网盘拉新等&#xff0c;最后我给他们的建议是网盘拉新项目。 该项目算比较老了&#xff0c;但确实是一个比较赚钱…

探索Codigger文件管理器(File Explorer)的创新与实用性

在数字时代&#xff0c;文件资源管理器作为桌面环境中不可或缺的一部分&#xff0c;承担着管理文件和文件夹的重要职责。Codigger文件管理器&#xff08;File Explorer&#xff09;以其独特的创新和实用性&#xff0c;为用户提供了高效、便捷的文件管理体验。 Codigger文件管理…

k8s 的 pod 基础 2

一、pod的镜像拉取策略 &#xff08;image PullPolicy&#xff09; Pod 的核心是运行容器&#xff0c;必须指定容器引擎&#xff0c;比如 Docker&#xff0c;启动容器时&#xff0c;需要拉取镜像&#xff0c;k8s 的镜像拉取策略可以由用户指定&#xff1a; 1、IfNotPresent &…

NTLM Relay Gat:自动化NTLM中继安全检测工具

关于NTLM Relay Gat NTLM Relay Gat是一款功能强大的NTLM中继威胁检测工具&#xff0c;该工具旨在利用Impacket工具套件中的ntlmrelayx.py脚本在目标环境中实现NTLM中继攻击风险检测&#xff0c;以帮助研究人员确定目标环境是否能够抵御NTLM中继攻击。 功能介绍 1、多线程支持…

关于如何在 smartforms 中 debug

发现一旦smartforms 复杂起来&#xff0c;Debug的时候就一下子找不到指定位置&#xff0c;所以如何才能最简单的找到指定位置呢 以这个为案例 然后打上断点即可debug

Science Advances|柔性超韧半导体纤维的大规模制备(柔性半导体器件/可穿戴电子/纤维器件/柔性电子)

北京大学 雷霆(Ting Lei)团队,在《Science Advances》上发布了一篇题为“Continuous production of ultratough semiconducting polymer fibers with high electronic performance”的论文。论文内容如下: 一、 摘要 共轭聚合物具有良好的光电特性,但其脆性和机械特性差,…

华大单片机下载报错“Error:Flash Download failed-“Cortex-M4””

Error&#xff1a;Flash Download failed-“Cortex-M4” 问题说明 使用华大单片机HC32F460KETA下载程序时&#xff0c;出现关于M4核的报错&#xff0c;具体如下&#xff1a; 此种情况下代码编译时没有问题的&#xff0c;只是下载时就会显示错误。 解决方法 注意最后一步选默…

【计算机毕业设计】388微信小程序足球赛事及队伍管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

[C#]使用C#部署yolov8-cls的图像分类的tensorrt模型

【测试通过环境】 win10 x64 vs2019 cuda11.7cudnn8.8.0 TensorRT-8.6.1.6 opencvsharp4.9.0 .NET Framework4.7.2 NVIDIA GeForce RTX 2070 Super 版本和上述环境版本不一样的需要重新编译TensorRtExtern.dll&#xff0c;TensorRtExtern源码地址&#xff1a;TensorRT-CShar…

DOM型XSS

前言 什么是DOM型XSS DOM型XSS漏洞是一种特殊类型的XSS,是基于文档对象模型 Document Object Model (DOM)的一种漏洞。 什么是DOM DOM全称Document Object Model,是一个与平台、编程语言无关的接口&#xff0c;它允许程序或脚本动态地访问和更新文档内容、结构和样式&#xff0…

门店系统会员开卡办卡库存收银小程序开发

门店系统会员开卡办卡库存收银小程序开发 一款专门针对门店管理开发的管理系统 系统支持电脑端收银、手机端收银、以及安装apk到安卓收银机收银。 支持门店客户开卡、办卡。支持会员卡、次卡、时卡、通卡。 支持门店进行线上线下营销&#xff0c;可以免费生成店铺专属小程序…

linux开发之设备树五、设备树描述中断实践

设备树是基于设备总线模型的&#xff08;platform&#xff09; 1、添加节点 假设中断引脚为&#xff1a;GPIO0_B5 下面使用设备树来描述它 1、写节点&#xff0c;起节点名字 这里用了ft5x06的触摸芯片&#xff0c;然后I2C的地址为38 2、为节点添加属性 首先添加compatible…