1、注解切入
1.1、@spirngBootApplication
1.2、复合注解
复合注解:就像类的继承关系一样。注解的上面还有注解
1.2.1、1
上图的1是Java的原注解:
@Target:标记这个注解应该是哪种 Java 成员、作用的范围。具体的值参照:ElementType
TYPE, 类、接口(包括注释类型)或枚举声明
FIELD, 字段声明(包括枚举常量)
METHOD, 方法声明
PARAMETER, 参数声明
CONSTRUCTOR, 构造方法声明
LOCAL_VARIABLE, 局部变量声明
ANNOTATION_TYPE, 注释类型声明
PACKAGE 包声明
@Retention:标识注解的存在阶段。
分为三个阶段:①RetentionPolicy.SOURCE:注解仅存在于源码中
②RetentionPolicy.CLASS:默认的存在阶段,注解会在class字节码文件中存在,但运行时无法获得
③RetentionPolicy.RUNTIME:注解会在class字节码文件中存在,在运行时可以通过反射获取到
@Documented:只是用来做标识,没什么实际作用。自定义注解的时候可以使用@Documented来进行标注,如果使用@Documented标注了,在生成javadoc的时候就会把@Documented注解给显示出来
@Inherited:注解继承:一个被@Inherited注解了的注解修饰了一个父类,如果他的子类没有被其他注解修饰,则它的子类也继承了父类的注解
1.2.2、2@SpringBootConfiguration
点击进入后发现@SpringbootConfigration的注解上还被@Configuration注解修饰。
说明@Configuration是@SpringbootConfigration的爹。@SpringbootConfigration这个注解就是孩子。也就是这个注解@SpringbootConfigration的功能比@Configuration还全面。(孩子继承父注解的所有参数功能,而且自己里面还有其他参数)
总结:springBoot在写配置类的时候也可以使用@SpringbootConfigration来标识
1.2.3、3@EnableAutoConfiguration
使能自动配置
@Import(AutoConfigurationImportSelector.class)作用:在这个注解类实例化完后自动实例化AutoConfigurationImportSelector.class这个类
1.2.4、4@ComponentScan
springBoot的包扫描注解
1.3、看了一会儿注解也没有找到入口换个方式看看
2、SpringBoot的真正入口
那些注解就相当于一个标记。也就是在springboot框架在运行的时候找到相关注解再来使用。
而真正的SpirngBoot还是main()方法的run函数
通过代码跟进,发现这行代码。获取spring工厂实例,设置初始化应用程序。
getSpringFactoriesInstances(ApplicationContextInitializer.class));关键代码。获取工厂实例具体做了什么。
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
通过type(ApplicationContextInitializer.class)和类加载器。加载了工厂类的名字;
1、获取所有工厂类的名字
4、如果缓存中没有数据,就通过一个路径去加载一个指定的资源
classLoader.getResources(FACTORIES_RESOURCE_LOCATION)
面试回答:通过类加载器获取我们的配置资源,
问:为什么要使用类加载器去加载,配置文件?
因为类加载器具有通用性,只要其他工程中有这个文件也一并加载进来。也就是如果去读取某一个类的配置的话就没有广泛性了。
举例:我们在创建springBoot工程的时候也可以创建META-INF文件夹下创建spring.factories文件。在springBoot工程启动的时候,除了springBoot工程下的spring.factories和我们自己工程下的这个文件都会被类加载器加载。
2.1、springBoot框架中找哈这个文件
举例:在spring Boot项目启动的时候,就会拿到一个清单文件。这个清单文件里面存放的是,springBoot能够整合的所有第三方框架的所有配置文件的路径 。
例如springboot中整合redis
这个配置文件熟悉吧。
tips:21~145 说明springBoot框架默认支持的Java框架多达一百多种。几乎涵盖所有的Java常用框架的支持
但是spring boot在程序启动的时候不可能包所有的框架配置加载完晒,所以就有判断。是否导入过相关框架的maven包。如果导入了就加载默认配置文件。
2.2、@ConditionalOnClass条件注解
还是那redis配置文件举例。
当前类文件夹下是否有RedisOperations.class类。如果有就说名导了包,就配置
@ConditionalOnClass(RedisOperations.class)
条件注解:当某一个条件成立的时候下面的配置类才自动配置。
2.3、@EnableConfigurationProperties(RedisProperties.class)
自动配置属性注解:就是在写yml配置时里面可以写的参数
配置属性其实都是用Java类进行封装好了的。
redis:
open: false # 是否开启redis缓存 true开启 false关闭
database: 0
host: localhost
port: 6379
password: # 密码(默认为空)
timeout: 6000ms # 连接超时时长(毫秒)
jedis:
pool:
max-active: 1000 # 连接池最大连接数(使用负值表示没有限制)
max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
2.4、@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
@Import注解,就是先把自己这个类实例化完成,然后才会去加载里面的两个配置类
白话:@Import注解下面代码执行完了还得执行注解数组里面的两个类里面的代码。
2.5、@ConditionalOnMissingBean(name = “redisTemplate”)
在spring Ioc容器中没有名字为redisTemplate的Bean时才会执行下面的代码。初始化redisTemplate对象放入IOC容器
tipic:没有给明name属性,默认选方法名,做验证
总结:每次springboot项目初始化的时候,都会加载spring.factories文件,加载到文件的时候,可以读取每一个自动配置的项,通过自动配置的全路径找到只鹅哥类,找到这个类之后 在通过条件注解 判断 当前环境下是够有指定的类存在,如果存在 就自动配置 否则就不配置