SpringBoot源码分析

1、如何将加载机制到IOC容器中

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringParentApplication {

public static void main(String[] args) {
SpringApplication.run(SpringParentApplication.class, args);
}

}

在执行main函数启动的时候,就会调用类加载器去加载对应的bean,全部放入到IOC容器中

  • 什么是类加载器
    • 就是SpringApplication.run(HqLmsServerApplication.class, args);中的:HqLmsServerApplication.class这个传递了一个类,传递了这个类的目的就是为了触发类加载器
  • 可以传递别的类?
    • 不可以,主类上有一个注解@SpringBootApplication是核心注解.这个注解就去加载项目中对应的所有的bean.这些bean就包含项目@Configu ration+@Bean的初始化、@Import机制(starter)那些类等等
  • 为什么要触发类加载器:
    • 可以获取上下文环境,可以能获取系统的信息
    • 会加载所有依赖jar中编译好的类
    • 会加载jdk对应的api

2、如何做到零配置(少量配置文件)

  • @Configuration+@Bean
  • @SelectorImport机制
  • @ImportResource
  • @ComponentScan+注解(@Service、@Controller、@RestController、@Component 、@Repository)

3、Springboot提供的@SpringBootApplication

@SpringBootApplication它是一个复合注解:

  • @Configuration+@Bean
  • @SelectorImport机制
  • @ImportResource
1
2
3
4
5
6
7
8
9
// Java原生注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// Spring核心注解
@SpringBootConfiguration: 等同与@Configuration(@Component)+@Bean
@EnableAutoConfiguration:开关注解+@SelectorImport机制来加载bean到ioc容器中
@ComponentScan+注解(@Service@Controller@RestController@Component@Repository)

@EnableAutoConfiguration:这个开关注解+@SelectorImport机制来加载bean到ioc容器中.同时它也是去加载项目中starter机制到注解.

4、@Import机制+@Eablexxxx机制

1.@EnableAutoConfiguration源码
1
2
3
4
5
6
7
8
9
10
11
12
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};

}

核心代码

1
@Import(AutoConfigurationImportSelector.class)

@Import机制,里面放入了class,class为Configuration或ImportSelector的类

2.尝试编写一个@Import例子
3.已经有了@ComponentScan+注解+@Configuration+@Bean和为什么还要有这个机制

因为SpringBoot到特点是:零配置(无xml文件),提供这几种机制可以方便的把bean放入到ioc容器中在开发中,除了自己开发的bean之外,还需要使用很多其它框架提供的bean.如mybatis需要一个datasoruce

传统方式

1
2
3
4
<bean id="dataSoruce"></bean>
<bean id="sqlsessionFactory" class="sqlsessionfactoryBean">
<property name="datasource" ref="datasource"/>
</bean>

为何用@Import代替@ComponentScan+注解?

答案:因为@ComponentScan+注解默认情况下是根据当前的启动的类把作为入口进行bean查找。如果第三方那么就必须一个个去配置它包。如果你引1入第三方的模板有50个。甚至更多你必须扫包.

1
@ComponentScan(basePackages={"com.asia","org.mybatis","org.xxx"...})

5、SpringBoot工程和项目如何找到/MET-INF/spring.factories这个文件的?

真正具体的触发和执行@Import(AutoConfigurationImportSelector.class) 这个类中selectImports方法是在哪里调用的

1.启动主类

1
2
3
public static void main(String[] args) {
SpringApplication.run(SpringParentApplication.class, args);
}

2.run方法

1
2
3
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}

3.执行一个run方法的重载,new 初始化和.run执行所有加载的bean放入ioc容器中

1
2
3
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}

初始化

1
new SpringApplication(primarySources)

运行加载

1
.run(args);