2022年7月12日 作者 zeroheart

Springboot学习专题

参考视频:SpringBoot源码分析_哔哩哔哩_bilibili

1.springboot的零配置是怎么解决的?SpringBoot源码分析_哔哩哔哩_bilibili

1.传统方式:

1.1 xml applicationxxx.xml

<bean id=’xx’ xxx>

1.2 扫包+注解

xml <compnant-scan basepakge=’xxxx’> + 注解 @Service @Controller @Repository @Component 等

2.springboot

2.1扫包+注解

@ComponentScan + 注解

2.2 @Configuration+@Bean

2.3

@Import机制

@Import(配置类&selector接口的实现类、普通的bean)

@Import(RedisConfiguration.class)

@Import(XXXselector.class)

@Import(xxxxService.class)

@ImportResource (xmlpath)

2.springboot的零配置解决什么问题?SpringBoot源码分析_哔哩哔哩_bilibili

通过不同的方式,把项目中和第三方中的依赖的bean,放入到spring的ioc容器中,基础核心还是spring,是通过新的一些方式来改进spring的机制

项目中的bean:

第三方的bean:

第三方bean怎么加进来?可以增加包扫描,当时不灵活

3.@Import机制,处理第三方bean的依赖SpringBoot源码分析_哔哩哔哩_bilibili

需要@Import机制,处理第三方bean的依赖,就是所谓的starter机制。

1.官方的xxx-starter-xxx,依赖不需要加入版本,有parent处理

2.第三方的xxx–xxx-starter,需要增加版本号

4.如何将bean放入ioc SpringBoot源码分析_哔哩哔哩_bilibili

4.1初始化阶段

初始化调用构造函数、初始化数组,开关等
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.sources = new LinkedHashSet();
    this.bannerMode = Mode.CONSOLE;
    this.logStartupInfo = true;
    this.addCommandLineProperties = true;
    this.addConversionService = true;
    this.headless = true;
    this.registerShutdownHook = true;
    this.additionalProfiles = Collections.emptySet();
    this.isCustomEnvironment = false;
    this.lazyInitialization = false;
    this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
    this.applicationStartup = ApplicationStartup.DEFAULT;
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();

//核心代码1
    this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    
//核心代码2
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
    
//核心代码3
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = this.deduceMainApplicationClass();
}

三个核心方法都在调用

getSpringFactoriesInstances
this.bootstrapRegistryInitializers = new ArrayList(this.getSpringFactoriesInstances(BootstrapRegistryInitializer.class));

触发类加载器,为类增加缓存,给后面的ApplicationContextInitializer和ApplicationListener使用

this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));

this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));


getSpringFactoriesInstances
启动时候,通过类加载器获取所有的类,放入jvm,然后过滤符合扫包之列的丢入ioc中

loadSpringFactories 
过滤factories中的类

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

4.2运行阶段

这里会调用到autoconfiguration的import方法中,使用条件注解进行过滤@conditionalXXX

4.3如何和springioc关联

run方法调用spring的refresh

4.4spring的生命周期

refresh方法中的处理