1. 程式人生 > 其它 >springboot2專題之第三篇:自動配置原理

springboot2專題之第三篇:自動配置原理

1、SpringBoot特點

1.1、依賴管理

父專案做依賴管理

依賴管理    
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.4.RELEASE</version>
</parent>

parent的父專案
 <parent>
    <groupId
>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.3.4.RELEASE</version> </parent> 幾乎聲明瞭所有開發中常用的依賴的版本號,自動版本仲裁機制

開發匯入starter場景啟動器

啟動器參照地址:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

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、所有場景啟動器最底層的依賴
<dependency>
  <groupId>org.springframework.boot</
groupId> <artifactId>spring-boot-starter</artifactId> <version>2.3.4.RELEASE</version> <scope>compile</scope> </dependency>

無需關注版本號,自動版本仲裁

1、引入依賴預設都可以不寫版本
2、引入非版本仲裁的jar,要寫版本號。

可以修改預設版本號

1、檢視spring-boot-dependencies裡面規定當前依賴的版本 用的 key。
2、在當前專案裡面重寫配置
    <properties>
        <mysql.version>5.1.43</mysql.version>
    </properties>

1.2、自動配置

  • 自動配好Tomcat
    • 引入Tomcat依賴。
    • 配置Tomcat
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
      <version>2.3.4.RELEASE</version>
      <scope>compile</scope>
    </dependency>
  • 自動配好SpringMVC
    • 引入SpringMVC全套元件
    • 自動配好SpringMVC常用元件(功能)
  • 自動配好Web常見功能,如:字元編碼問題
    • SpringBoot幫我們配置好了所有web開發的常見場景
  • 預設的包結構
    • 主程式所在包及其下面的所有子包裡面的元件都會被預設掃描進來
    • 無需以前的包掃描配置
    • 想要改變掃描路徑,@SpringBootApplication(scanBasePackages="com.stu")
    • 或者@ComponentScan 指定掃描路徑

參考地址:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.structuring-your-code

@SpringBootApplication
等同於
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.stu.boot")
  • 各種配置擁有預設值
    • 預設配置最終都是對映到某個類上,如:MultipartProperties
    • 配置檔案的值最終會繫結每個類上,這個類會在容器中建立物件
  • 按需載入所有自動配置項
    • 非常多的starter
    • 引入了哪些場景這個場景的自動配置才會開啟
    • SpringBoot所有的自動配置功能都在 spring-boot-autoconfigure
    • ......

2、容器功能

2.1、元件新增

1、@Configuration

  • 基本使用
  • Full模式與Lite模式
    • 示例
    • 最佳實戰
    • 配置 類元件之間無依賴關係用Lite模式加速容器啟動過程,減少判斷
    • 配置類元件之間有依賴關係,方法會被呼叫得到之前單例項元件,用Full模式
#############################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));



    }
}

2、@Bean、@Component、@Controller、@Service、@Repository

3、@ComponentScan、@Import

 * 4、@Import({User.class, DBHelper.class})
 *      給容器中自動創建出這兩個型別的元件、預設元件的名字就是全類名
 *
 *
 *
 */

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告訴SpringBoot這是一個配置類 == 配置檔案
public class MyConfig {
}

4、@Conditional

條件裝配:滿足Conditional指定的條件,則進行元件注入

=====================測試條件裝配==========================
@Configuration(proxyBeanMethods = false) //告訴SpringBoot這是一個配置類 == 配置檔案
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
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、原生配置檔案引入

1、@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。
         }
     }
 }

1、@ConfigurationProperties

server.port=8888

spring.servlet.multipart.max-file-size=10MB


mycar.brand=YD
mycar.price=100000


#server.servlet.encoding.charset=GBK
debug=true

spring.banner.image.location=classpath:222.jpg

注意配置類沒有自動註解EnableConfigurationProperties的時候,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 +
                '}';
    }
}

測試,看通過ConfigurationProperties註解讀取屬性檔案的方式是否成功。

package com.stu.controller;

import com.atguigu.boot.bean.Car;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

//@ResponseBody
//@Controller

// JRebel
@Slf4j
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(@RequestParam("name") String name){


        log.info("請求進來了....");
        return "Hello, Spring Boot 2!"+"你好:"+name;
    }

    @Autowired
    Car car;


    @RequestMapping("/car")
    public Car car(){
        return car;
    }



}

2、@EnableConfigurationProperties + @ConfigurationProperties(如果是引用第三方包沒有component就需要這個方式了)

car需要跟配置類繫結

package com.atguigu.boot.config;


import ch.qos.logback.core.db.DBHelper;
import com.atguigu.boot.bean.Car;
import com.atguigu.boot.bean.Pet;
import com.atguigu.boot.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.filter.CharacterEncodingFilter;


/**
 * 1、配置類裡面使用@Bean標註在方法上給容器註冊元件,預設也是單例項的
 * 2、配置類本身也是元件
 * 3、proxyBeanMethods:代理bean的方法
 *      Full(proxyBeanMethods = true)、【保證每個@Bean方法被呼叫多少次返回的元件都是單例項的】
 *      Lite(proxyBeanMethods = false)【每個@Bean方法被呼叫多少次返回的元件都是新建立的】
 *      元件依賴必須使用Full模式預設。其他預設是否Lite模式
 *
 * 4、@Import({User.class, DBHelper.class})
 *      給容器中自動創建出這兩個型別的元件、預設元件的名字就是全類名
 *
 *
 * 5、@ImportResource("classpath:beans.xml")匯入Spring的配置檔案,
 *
 */

@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告訴SpringBoot這是一個配置類 == 配置檔案
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
@ImportResource("classpath:beans.xml")
//@EnableConfigurationProperties(Car.class)
//1、開啟Car配置繫結功能
//2、把這個Car這個元件自動註冊到容器中
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");
    }

//    @Bean
//    public CharacterEncodingFilter filter(){
//        return null;
//    }
}

配置類標註EnableConfigurationProperties註解car類不需要寫@Component註解了

package com.atguigu.boot.bean;


import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;


/**
 * 只有在容器中的元件,才會擁有SpringBoot提供的強大功能
 */
@ToString
@Data
//@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {

    private String brand;
    private Integer price;


}

3、@Component + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)
//1、開啟Car配置繫結功能
//2、把這個Car這個元件自動註冊到容器中
public class MyConfig {
}

3、自動配置原理入門

3.1、引導載入自動配置類

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication{}


======================
    

1、@SpringBootConfiguration
@Configuration。代表當前是一個配置類

2、@ComponentScan
指定掃描哪些,Spring註解;

3、@EnableAutoConfiguration

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}

1、@AutoConfigurationPackage

自動配置包?指定了預設的包規則

@Import(AutoConfigurationPackages.Registrar.class)  //給容器中匯入一個元件
public @interface AutoConfigurationPackage {}

//利用Registrar給容器中匯入一系列元件
//將指定的一個包下的所有元件匯入進來?MainApplication 所在包下。

2、@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
    
檔案裡面寫死了spring-boot一啟動就要給容器中載入的所有配置類
spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories
# 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,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

3.2、按需開啟自動配置項

雖然我們127個場景的所有自動配置啟動的時候預設全部載入。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、最佳實踐

  • 引入場景依賴
  • 檢視自動配置了哪些(選做)
    • 自己分析,引入場景對應的自動配置一般都生效了
    • 配置檔案中debug=true開啟自動配置報告。Negative(不生效)\Positive(生效)
  • 是否需要修改
    • 參照文件修改配置項
    • 自定義加入或者替換元件
    • @Bean、@Component。。。
    • 自定義器 XXXXXCustomizer
    • ......

4、開發小技巧

4.1、Lombok

簡化JavaBean開發

  <dependency>
     <groupId>org.projectlombok</groupId>
     <artifactId>lombok</artifactId>
  </dependency>

idea中搜索安裝lombok外掛
===============================簡化JavaBean開發===================================
@NoArgsConstructor
//@AllArgsConstructor
@Data
@ToString
@EqualsAndHashCode
public class User {

    private String name;
    private Integer age;

    private Pet pet;

    public User(String name,Integer age){
        this.name = name;
        this.age = age;
    }


}



================================簡化日誌開發===================================
@Slf4j
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String handle01(@RequestParam("name") String name){
        
        log.info("請求進來了....");
        
        return "Hello, Spring Boot 2!"+"你好:"+name;
    }
}

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(專案初始化嚮導)

0、選擇我們需要的開發場景

選擇web

選擇mybatis

點選next,finish。

可以刪除多餘的檔案,刪除後如下圖

展開後

生成的pom,注意這裡的依賴是自動生成的

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.stu</groupId>
    <artifactId>boot-init</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>boot-init</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

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

</project>