1.自动装配原理
1.@Import
@Import注解有三种用法我们知道,使用@Import是一种很好的导入Bean定义信息的方式 弊端: 但是使用这个@Import三种用法导入的,无法保证顺序,比如整合Mybatis时,我们有SqlSessionFactory,那么如果我们自己个性化配置的SqlSessionFactory就无法在这个默认的前面加载 Spring中使用了 DeferredImportSelector接口的方式,实现这个接口并标识@Import的类可以在 @ComponentScan @Import(processImports方法) @ImportResurce @Bean注解以后进行执行,执行selectImports方法,这样就保证了我们自定义的@Bean注入的对象可以完美的在框架整合之前完成定义信息的注入 同时还提供了分组的功能,在一个大的DeferredImportSelector可以有很多分组,分组之间依然可以控制成一个有序的过程 SpringBoot自动装配的类,一定不在@ComponentScan可以扫描的地方,所以才用@Import
2.Spring.factories
上面的@Import可以进行Bean信息的注入了,那么注入些什么? 我们只有在pom中引入一些包时,才能注入一些Bean,比如SqlSessionFactory 在@Import环节,Spring扫描所有jar包的Spring.factories中定义的要注入的类,放到一个List集合中,这样就算不是我们SpringBoot带的,我们自己整合的MyBatis的,Redis的都可以注入到容器中 但是并不是所有的Spring.factories下的都要加载,SpringBoot启动时,只会解析Spring.factories文件中K为EnableAutoConfiguration的,官方的就有127个
3.ConditionalOn
有了 Spring.factories下的EnableAutoConfiguration的类,还不能直接将这些类进行再次 判定 这些类上有大量的ConditionalOnXXX注解,这些注解中定义了一些判定规则,满足规则才会真实的创建Bean对象 比如SqlSessionFactory上面有@ConditiOnBean(SqlSessionFactory.class)我们前面使用了@Bean的方式配置了这个类,就不会再次注入
4.自定义Spring.factories
我们知道,SpringBoot默认的spring.factories有很多默认不导入其他jar包就加载的配置类,那么为什么只有127个,常用的mybatis就没有呢? 因为SpringBoot只维护自己Spring生态的,它不想和Mybatis玩,但是我们第三方的确可以利用SpringBoot的扫描所有jar包下Spring.factories这个文件的特性,自己写一个,让Spring加载
2.启动原理
1.SpringBoot打包插件
我们运行 java -jar做了什么? 官网说: java -jar会去找jar中的manifest文件,在manifest文件中有Main-Class的定义,Main-Class的源码中指定了整个应用的启动类 我们不使用Spring打包插件打成的jar包,没有manifest文件,所以运行不了 那么使用了打包插件,创建了manifest文件,并指定了Main-Class就可以了吗? 还是不行,SpringBoot项目一个jar包中还包含了我们pom引入的大量jar包,而 java -jar命令是没有解析内部jar包的能力的 因此在manifest文件中定义的Main-Class 是: Main-Class: org.springframework.boot.loader.JarLauncher 而这个JarLauncher类加载器就是用来加载内层jar包的 那么Main-Class已经被使用了,我们SpringBoot的主函数怎么指定呢? Start-Class: com.XXXX.Application 这个定义是Spring级别的,由框架调用,不再由java -jar的命令来调用
META-INF/MANIFEST.MF 是这样的:
Manifest-Version: 1.0
Implementation-Title: spring-learn
Implementation-Version: 0.0.1-SNAPSHOT
Start-Class: com.tulingxueyuan.Application
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.1.5.RELEASE
Created-By: Maven Archiver 3.4.0
Main-Class: org.springframework.boot.loader.JarLauncher
1. JarLauncher通过加载BOOT-INF/classes目录及BOOT-INF/lib目录下jar文件,实现了fat jar的启动。 2. SpringBoot通过扩展JarFile、JarURLConnection及URLStreamHandler,实现了jar in jar中资源的加载。 3. SpringBoot通过扩展URLClassLoader–LauncherURLClassLoader,实现了jar in jar中class文件的加载。 4. WarLauncher通过加载WEB-INF/classes目录及WEB-INF/lib和WEB-INF/lib-provided目录下的jar文件,实现了war文件的直接启动及web容器中的启动。
2.主函数Run方法
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
//对于一个SpringBoot主函数首先要在run中传入启动类.class
1. 创建Spring容器主要有两种方法 new AnnotationApplicationContext(); 需要传一个配置类 new ClassPathXmlApplicationContext(); 需要传一个xml配置文件 而我们的启动类注解中恰好通过@Configuration表示启动类是一个配置类,所以run方法传的就是启动类