spring-boot 之自动装配机制的原理分析

文章目录

  • 1.入口类@SpringBootApplication
    • 1.1.概述
    • 1.2. @SpringBootApplication 该注解主要组合了以下注解:
      • 1.2.1.@SpringBootConfiguration
        • 1.2.1.1.概述
        • 1.2.1.2.@Configuration(通过案例介绍@Configuration)
          • 1.2.1.2.1.概述
          • 1.2.1.2.2.案例演示
            • 1.2.1.2.2.1.定义一个Bean类:ConfigurationBean
            • 1.2.1.2.2.2.定义一个Configuration类:ConfigurationDemo,扫描Bean
            • 1.2.1.2.2.3.定义一个测试类:ConfigurationMain
        • 1.2.1.3.@Configuration本质上是@Component
      • 1.2.2.@EnableAutoConfiguration
        • 1.2.2.1.概述
        • 1.2.2.2.Import
          • 1.2.2.2.1.前期准备
            • 1.2.2.2.1.1.First文件夹
            • 1.2.2.2.1.2.Second文件夹
          • 1.2.2.2.2.案例一:不使用import,只能引用当前包下的Bean
          • 1.2.2.2.2.案例二:使用import,引用别的包下面的bean
        • 1.2.2.3.ImportSelector
          • 1.2.2.3.1.UserLoginService和UserBusinessService:创建两个Bean
          • 1.2.2.3.2.EnableUserDefineService【自定义一个注解】
          • 1.2.2.3.3.UserImportSelector
          • 1.2.2.3.5.UserMain
        • 1.2.2.4.ImportBeanDefinitionRegistrar
          • 1.2.2.4.1.UserLogginDefinitionRegistrar:定义注册Registrar,实现ImportBeanDefinitionRegistrar
          • 1.2.2.4.2.UserMain:导入UserLogginDefinitionRegistrar,进行测试,看是否注入UserLoginService的bean
        • 1.2.2.5.SPI:回到@EnableAutoConfiguration的AutoConfigurationImportSelector
          • 1.2.2.5.1.源码
            • 1.2.2.5.1.1.AutoConfigurationImportSelector.selectImports()方法
            • 1.2.2.5.1.2.AutoConfigurationMetadataLoader.loadMetadata()加载spring-autoconfigure-metadata.properties
            • 1.2.2.5.1.3.加载上面Configuration中的Bean(最终在 META-INF/spring.factories)
          • 1.2.2.5.2.案例:自定义META-INF/spring.factories
            • 1.2.2.5.2.1.创建新项目demo-spring-boot-example-05
            • 1.2.2.5.2.2.创建MyBean和MyConfig类
            • 1.2.2.5.2.3.创建spring.fatories
            • 1.2.2.5.2.4.demo-spring-boot-example-04项目中引入demo-spring-boot-example-05
            • 1.2.2.5.2.5.demo-spring-boot-example-04项目创建SpiMain进行测试
            • 1.2.2.5.2.6.总结
        • 1.2.2.6.Spring条件注入
          • 1.2.2.6.1.demo-spring-boot-example-05项目中新增spring-autoconfigure-metadata.properties
          • 1.2.2.6.2.demo-spring-boot-example-05项目版本升级0.0.2
          • 1.2.2.6.3.demo-spring-boot-example-04重新引用demo-spring-boot-example-05版本的0.0.2版本
          • 1.2.2.6.4.demo-spring-boot-example-04 类SpiMain开始测试
          • 1.2.2.6.5.demo-spring-boot-example-04 创建MyTest类,再次进行测试
      • 1.2.3.@ComponentScan
        • 1.2.3.2.案例
          • 1.2.3.2.1.ComponentScanBean
          • 1.2.3.2.2.ComponentScanMain
        • 1.2.3.3.设置扫描的路径
  • 2. 关闭自动配置
  • 3.自定义Banner
  • 4.全局配置文件
    • 4.1.spring-boot 默认配置文件路径
  • 5.Starter pom
  • 6.Xml配置文件
  • 7.日志

1.入口类@SpringBootApplication

1.1.概述

Spring Boot的项目一般都会有*Application的入口类,入口类中会有main方法,这是一个标准的Java应用程序的入口方法。
@SpringBootApplication注解是Spring Boot的核心注解,它其实是一个组合注解:

spring-boot 之自动装配机制的原理分析_第1张图片

1.2. @SpringBootApplication 该注解主要组合了以下注解:

1.2.1.@SpringBootConfiguration

1.2.1.1.概述

1.	@SpringBootConfiguration:这是Spring Boot项目的配置注解,这也是一个组合注解:
2.	在Spring Boot项目中推荐使用@SpringBootConfiguration替代@Configuration
    所谓的替代,我们可以简单地理解,SpringBoot里面@SpringBootConfiguration就是@Configuration换了一个名字而已

spring-boot 之自动装配机制的原理分析_第2张图片

1.2.1.2.@Configuration(通过案例介绍@Configuration)

源代码
https://gitee.com/gaoxinfu_admin/demo-spring-boot/tree/master/demo-spring-boot-example-04/src/main/java/com/gaoxinfu/demo/springboot/componentscan

1.2.1.2.1.概述
1.Configuration 这个注解大家应该有用过,它是 JavaConfig形式的基于Spring IOC容器的配置类使用的一种注解。
  因为SpringBoot 本质上就是一个spring 应用,所以通过这个注解来加载 IOC 容器的配置是很正常的。所以在启动类
  里面标注了@Configuration,意味着它其实也是一个IoC容器的配置类。
2.传统意义上的 spring 应用都是基于 xml 形式来配置 bean的依赖关系。然后通过 spring 容器在启动的时候,把bean
  进行初始化并且,如果 bean 之间存在依赖关系,则分析这些已经在 IoC 容器中的 bean 根据依赖关系进行组装。
3.直到 Java5 中,引入了 Annotations 这个特性,Spring 框架也紧随大流并且推出了基于Java代码和 Annotation元
  信息的依赖关系绑定描述的方式。也就是JavaConfig。 
  从spring3 开始,spring 就支持了两种 bean 的配置方式,一种是基于 xml 文件方式、另一种就是 JavaConfig
1.2.1.2.2.案例演示
1.2.1.2.2.1.定义一个Bean类:ConfigurationBean
package com.gaoxinfu.demo.springboot.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 16:56
 */
public class ConfigurationBean {

    public void say(){
        System.out.println("say() = Hello");
    }
}

1.2.1.2.2.2.定义一个Configuration类:ConfigurationDemo,扫描Bean
package com.gaoxinfu.demo.springboot.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 16:55
 */
@Configuration
public class ConfigurationDemo {

    @Bean
    public ConfigurationBean configurationBean(){
        return new ConfigurationBean();
    }
}
1.2.1.2.2.3.定义一个测试类:ConfigurationMain
package com.gaoxinfu.demo.springboot.configuration;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 16:56
 */
public class ConfigurationMain {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext AnnotationConfigApplicationContext=new AnnotationConfigApplicationContext(ConfigurationDemo.class);
        ConfigurationBean configurationBean= AnnotationConfigApplicationContext.getBean(ConfigurationBean.class);
        if (configurationBean!=null){
            configurationBean.say();
        }else{
            System.out.println("configurationBean = "+configurationBean);
        }

    }
}

spring-boot 之自动装配机制的原理分析_第3张图片

1.2.1.3.@Configuration本质上是@Component

spring-boot 之自动装配机制的原理分析_第4张图片

1.2.2.@EnableAutoConfiguration

1.2.2.1.概述

1.	@EnableAutoConfiguration:启用自动配置,
2.	该注解会使Spring Boot根据项目中依赖的jar包自动配置项目的配置项:

例如:

我们添加了spring-boot-starter-web的依赖,项目中也就会引入SpringMVC的依赖,
Spring Boot就会自动配置tomcat和SpringMVC

spring-boot 之自动装配机制的原理分析_第5张图片

EnableAutoConfiguration该注解包含两块 @AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})

spring-boot 之自动装配机制的原理分析_第6张图片

1.2.2.2.Import

源代码
https://gitee.com/gaoxinfu_admin/demo-spring-boot/tree/master/demo-spring-boot-example-04/src/main/java/com/gaoxinfu/demo/springboot/enableautoconfiguration/importdemo

1.2.2.2.1.前期准备

spring-boot 之自动装配机制的原理分析_第7张图片

1.2.2.2.1.1.First文件夹

FirstBean.java

package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.first;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:40
 */
public class FirstBean {
}
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.first;

import com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second.SecondBean;
import com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second.SecondConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;


**FirstConfig.java**
/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:40
 */
@Configuration
public class FirstConfig {

    @Bean
    public FirstBean firstBean(){
        return new FirstBean();
    }
}

FirstMain.java

package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.first;

import com.gaoxinfu.demo.springboot.configuration.ConfigurationBean;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:42
 */
public class FirstMain {
    public static void main(String[] args) {

        AnnotationConfigApplicationContext AnnotationConfigApplicationContext=new AnnotationConfigApplicationContext(FirstConfig.class);
        String[] beanDefinitionNames=AnnotationConfigApplicationContext.getBeanDefinitionNames();
        for (String beanDefinitionName:beanDefinitionNames){
            System.out.println("BeanDefinitionName = "+beanDefinitionName);
        }
    }
}
1.2.2.2.1.2.Second文件夹
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:42
 */
public class SecondBean {


}

package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:42
 */
@Configuration
public class SecondConfig {

    @Bean
    public SecondBean secondBean(){
        return  new SecondBean();
    }
}
1.2.2.2.2.案例一:不使用import,只能引用当前包下的Bean

直接运行上面的FirstMain.main方法,只会出现first文件夹下的,second下面的bean不会加载进来
spring-boot 之自动装配机制的原理分析_第8张图片

1.2.2.2.2.案例二:使用import,引用别的包下面的bean

FirstConfig.java

package com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.first;

import com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second.SecondBean;
import com.gaoxinfu.demo.springboot.enableautoconfiguration.importdemo.second.SecondConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 20:40
 */
@Configuration
@Import(SecondConfig.class)
public class FirstConfig {

    @Bean
    public FirstBean firstBean(){
        return new FirstBean();
    }
}

spring-boot 之自动装配机制的原理分析_第9张图片

再次运行FirstMain.main()方法,second文件夹bean引入
spring-boot 之自动装配机制的原理分析_第10张图片

1.2.2.3.ImportSelector

源代码
https://gitee.com/gaoxinfu_admin/demo-spring-boot/tree/master/demo-spring-boot-example-04/src/main/java/com/gaoxinfu/demo/springboot/enableautoconfiguration/importselectordemo

1.2.2.3.1.UserLoginService和UserBusinessService:创建两个Bean
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:05
 */
public class UserLoginService {
}

package com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:06
 */
public class UserBusinessService {
}

1.2.2.3.2.EnableUserDefineService【自定义一个注解】
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo;

import org.springframework.context.annotation.Import;

import java.lang.annotation.*;

/**
 * @Description: 启动用户定义的Service
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:07
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({UserImportSelector.class})
public @interface EnableUserDefineService {

    Class<?>[] exclude() default {};

}
1.2.2.3.3.UserImportSelector
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
import java.util.Map;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:06
 */
public class UserImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        Map<String,Object> attributes=
                annotationMetadata.getAnnotationAttributes(EnableUserDefineService.class.getName());
        //动态注入bean :自己去实现判断逻辑实现动态配置
        Class<?>[] excludeCLass= (Class<?>[]) attributes.get("exclude");

        //TODO 这里可以做判断,拉出UserBusinessService和UserLoginService等所有的(匹配到)
        //根据exclude 然后删除UserLoginService

        return new String[]{UserBusinessService.class.getName()}; //返回的是一个固定的UserBusinessService
    }
}

1.2.2.3.5.UserMain
package com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo;

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

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:11
 */
@SpringBootApplication
@EnableUserDefineService(exclude = {UserLoginService.class})
public class UserMain {

    public static void main(String[] args) {
        ConfigurableApplicationContext configurableApplicationContext
                =SpringApplication.run(UserMain.class,args);

        System.out.println(configurableApplicationContext.getBean(UserBusinessService.class));
    }
}

1.2.2.4.ImportBeanDefinitionRegistrar

1.2.2.4.1.UserLogginDefinitionRegistrar:定义注册Registrar,实现ImportBeanDefinitionRegistrar
package com.gaoxinfu.demo.springboot.enableautoconfiguration.ImportBeanDefinitionRegistrarDemo;

import com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo.UserLoginService;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.StringUtils;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 11:16
 */
public class UserLogginDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        Class beanClass= UserLoginService.class;
        RootBeanDefinition beanDefinition=new RootBeanDefinition(beanClass);
        String beanName= StringUtils.uncapitalize(beanClass.getSimpleName());
        registry.registerBeanDefinition(beanName,beanDefinition);
    }
}
1.2.2.4.2.UserMain:导入UserLogginDefinitionRegistrar,进行测试,看是否注入UserLoginService的bean
package com.gaoxinfu.demo.springboot.enableautoconfiguration.ImportBeanDefinitionRegistrarDemo;

import com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo.EnableUserDefineService;
import com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo.UserBusinessService;
import com.gaoxinfu.demo.springboot.enableautoconfiguration.importselectordemo.UserLoginService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 22:11
 */
@SpringBootApplication
@Import(UserLogginDefinitionRegistrar.class)
public class UserMain {

    public static void main(String[] args) {
        ConfigurableApplicationContext configurableApplicationContext
                =SpringApplication.run(UserMain.class,args);
        System.out.println(configurableApplicationContext.getBean(UserLoginService.class));
    }
}

spring-boot 之自动装配机制的原理分析_第11张图片

1.2.2.5.SPI:回到@EnableAutoConfiguration的AutoConfigurationImportSelector

1.2.2.5.1.源码

spring-boot 之自动装配机制的原理分析_第12张图片

1.2.2.5.1.1.AutoConfigurationImportSelector.selectImports()方法

spring-boot 之自动装配机制的原理分析_第13张图片

1.2.2.5.1.2.AutoConfigurationMetadataLoader.loadMetadata()加载spring-autoconfigure-metadata.properties

spring-boot 之自动装配机制的原理分析_第14张图片
spring-boot 之自动装配机制的原理分析_第15张图片

**对应类所在的包下面的 spring-autoconfigure-metadata.properties文件 主要是一些spring中的大部分的Configuration,先扫到,后面用那个再说
**

1.2.2.5.1.3.加载上面Configuration中的Bean(最终在 META-INF/spring.factories)

spring-boot 之自动装配机制的原理分析_第16张图片

   protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        } else {
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
            configurations = this.removeDuplicates(configurations);
            Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
            this.checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);
            configurations = this.filter(configurations, autoConfigurationMetadata);
            this.fireAutoConfigurationImportEvents(configurations, exclusions);
            return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
        }
    }

spring-boot 之自动装配机制的原理分析_第17张图片

 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

spring-boot 之自动装配机制的原理分析_第18张图片
spring-boot 之自动装配机制的原理分析_第19张图片

META-INF/spring.factories样例

1.2.2.5.2.案例:自定义META-INF/spring.factories

这里注意下,上面的key是可以进行扩展的,在别的地方定义的同样的key,其value也会被增加扩展加载进来

1.2.2.5.2.1.创建新项目demo-spring-boot-example-05

源码地址
https://gitee.com/gaoxinfu_admin/demo-spring-boot/tree/master/demo-spring-boot-example-05

1.2.2.5.2.2.创建MyBean和MyConfig类
package com.gaoxinfu.demo.spring.boot.example05.bean;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 14:19
 */
public class MyBean {
}

package com.gaoxinfu.demo.spring.boot.example05.bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 14:19
 */
@Configuration
public class MyConfig {

    @Bean
    public MyBean myBean(){
        return new MyBean();
    }
}
1.2.2.5.2.3.创建spring.fatories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.gaoxinfu.demo.spring.boot.example05.bean.MyConfig

spring-boot 之自动装配机制的原理分析_第20张图片

1.2.2.5.2.4.demo-spring-boot-example-04项目中引入demo-spring-boot-example-05

spring-boot 之自动装配机制的原理分析_第21张图片

1.2.2.5.2.5.demo-spring-boot-example-04项目创建SpiMain进行测试
package com.gaoxinfu.demo.springboot.enableautoconfiguration.spi;

import com.gaoxinfu.demo.spring.boot.example05.bean.MyBean;
import com.gaoxinfu.demo.spring.boot.example05.bean.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 14:24
 */
@SpringBootApplication
public class SpiMain {

    public static void main(String[] args) {
        ConfigurableApplicationContext ConfigurableApplicationContext
                =SpringApplication.run(SpiMain.class,args);
        System.out.println(ConfigurableApplicationContext.getBean(MyBean.class));
    }
}

spring-boot 之自动装配机制的原理分析_第22张图片

1.2.2.5.2.6.总结
1.可以看得出来,demo-spring-boot-example-05中的spring.factories中我们配置的MyBean这个类已经被加载IOC容器中了

1.2.2.6.Spring条件注入

1.2.2.6.1.demo-spring-boot-example-05项目中新增spring-autoconfigure-metadata.properties

spring-boot 之自动装配机制的原理分析_第23张图片

spring-autoconfigure-metadata.properties配置内容
即当com.gaoxinfu.demo.springboot.enableautoconfiguration.spi.MyTest这个类存在的时候,
才会加载MyConfig中的相关bean到IOC中

ConditionalOnClass

com.gaoxinfu.demo.spring.boot.example05.bean.MyConfig.ConditionalOnClass=com.gaoxinfu.demo.springboot.enableautoconfiguration.spi.MyTest
1.2.2.6.2.demo-spring-boot-example-05项目版本升级0.0.2

spring-boot 之自动装配机制的原理分析_第24张图片

1.2.2.6.3.demo-spring-boot-example-04重新引用demo-spring-boot-example-05版本的0.0.2版本

spring-boot 之自动装配机制的原理分析_第25张图片

1.2.2.6.4.demo-spring-boot-example-04 类SpiMain开始测试
package com.gaoxinfu.demo.springboot.enableautoconfiguration.spi;

import com.gaoxinfu.demo.spring.boot.example05.bean.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 14:24
 */
@SpringBootApplication
public class SpiMain {

    public static void main(String[] args) {
        ConfigurableApplicationContext ConfigurableApplicationContext
                =SpringApplication.run(SpiMain.class,args);
        System.out.println(ConfigurableApplicationContext.getBean(MyConfig.class));
    }
}

spring-boot 之自动装配机制的原理分析_第26张图片
因为spi文件夹下面没有MyTest类,导致MyConfig将Bean注入的IOC容器中spring-boot 之自动装配机制的原理分析_第27张图片

1.2.2.6.5.demo-spring-boot-example-04 创建MyTest类,再次进行测试
package com.gaoxinfu.demo.springboot.enableautoconfiguration.spi;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-19 16:48
 */
public class MyTest {
}

再次运行SpiMain中的Main方法,成功spring-boot 之自动装配机制的原理分析_第28张图片

1.2.3.@ComponentScan

@ComponentScan:默认扫描@SpringBootApplication所在类的同级目录以及它的子目录。

1.2.3.2.案例

1.2.3.2.1.ComponentScanBean
package com.gaoxinfu.demo.springboot.componentscan;

import org.springframework.stereotype.Service;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 16:56
 */
@Service
public class ComponentScanBean {

    public void say(){
        System.out.println("say() = Hello");
    }
}

1.2.3.2.2.ComponentScanMain
package com.gaoxinfu.demo.springboot.componentscan;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
 * @Description:
 * @Author: gaoxinfu
 * @Date: 2020-04-18 16:56
 */
@ComponentScan
public class ComponentScanMain {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext AnnotationConfigApplicationContext=new AnnotationConfigApplicationContext(ComponentScanMain.class);
        String[] definitionNames= AnnotationConfigApplicationContext.getBeanDefinitionNames();
        for(int i=0;i< definitionNames.length;i++){
            System.out.println("definitionName = "+definitionNames[i]);
        }

    }
}

会自动扫面到@Service的类ComponentScanBean
在这里插入图片描述

1.2.3.3.设置扫描的路径

1.也可以通过
@ComponentScan(basePackages = "com.gaoxinfu.demo.springboot.componentscan")
设置扫描的路径

spring-boot 之自动装配机制的原理分析_第29张图片

多个路径的话,可以用逗号分隔开

@ComponentScan(basePackages = "com.gaoxinfu.demo.springboot.componentscan,com.gaoxinfu.demo.springboot.configuration")

spring-boot 之自动装配机制的原理分析_第30张图片

2. 关闭自动配置

通过上述,我们得知,Spring Boot会根据项目中的jar包依赖,自动做出配置,
Spring Boot支持的自动配置如下(非常多):

spring-boot 之自动装配机制的原理分析_第31张图片

如果我们不需要Spring Boot自动配置,想关闭某一项的自动配置,该如何设置呢?
比如:我们不想自动配置Redis,想手动配置。

在这里插入图片描述

3.自定义Banner

启动Spring Boot项目后会看到这样的图案:
spring-boot 之自动装配机制的原理分析_第32张图片

这个图片其实是可以自定义的:
http://patorjk.com/software/taag/#p=display&f=Graffiti&t=Type%20Something%20
spring-boot 之自动装配机制的原理分析_第33张图片

拷贝生成的字符到一个文本文件中,并且将该文件命名为banner.txt
将banner.txt拷贝到项目的resources目录中:

在这里插入图片描述

重新启动程序,查看效果,会有新的图案显示

如果不想看到任何的banner,也是可以将其关闭的:
在这里插入图片描述

4.全局配置文件

4.1.spring-boot 默认配置文件路径

xxxx-autoconfigure-xxx.jar包下
有可能多个,下面是其中一个 spring-boot-autoconfigure-xxx.jar
spring-boot 之自动装配机制的原理分析_第34张图片

5.Starter pom

在这里插入图片描述

spring-boot 之自动装配机制的原理分析_第35张图片
spring-boot 之自动装配机制的原理分析_第36张图片
spring-boot 之自动装配机制的原理分析_第37张图片

6.Xml配置文件

spring-boot 之自动装配机制的原理分析_第38张图片

7.日志

Spring Boot对各种日志框架都做了支持,我们可以通过配置来修改默认的日志的配置:

#设置日志级别
logging.level.org.springframework=DEBUG
格式:
logging.level.*= # Log levels severity mapping. For instance `logging.level.org.springframework=DEBUG`

你可能感兴趣的:(spring-boot)