springboot如何实现自动扫描包和自动配置类的源码分析步骤

SpringBoot核心是@SpringBootApplication注解 打开这个注解
@Target({ElementType.TYPE}) 声明该注解是用在类上的 
@Retention(RetentionPolicy.RUNTIME) 声明该注解在运行时起作用
@Documented  可以生成文档
@Inherited  声明该注解可以被继承
前面四个是元注解
@SpringBootConfiguration  声明当前类是一个配置类


@SpringBootApplication的核心就是下面的注解
@EnableAutoConfiguration(启动自动配置)下的两个注解

如何完成<context:component-scan  basePackage="org.lanqiao"/>功能  
a.获取注解所在的包名 spring需要我们自己输入
b.springboot是自动获取包名进行扫描的 主要完成这个功能
源代码:
1打开@AutoConfigurationPackage(自动配置包)  
 2.打开@Import({Registrar.class})   import的功能就是把Registrar.class自动装载到IOC容器中
3..打开Registrar.class 找主要的方法registerBeanDefinitions()
   BeanDefinitions  负责管理Ioc容器中所有的bean对象
4. register.(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()); 通过注入的元数据metadata获取了这个包的名字 使用的debug调试这个语句的到的结果就是org.lanqiao
5.打开register 中可以发现   beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);  就会根据我们获取的包的名字来扫描包下的注解加入到ioc容器中

总:1.springboot 的特点的是约定优于配置,通过@EnableAutoConfiguration注解中的@AutoConfigurationPackage 来获取主应用程序所在的包名
2.然后使用beanDefinition根据包名完成扫描的该报下的所有注解把扫描的注解加到IOC容器中。
3.因此主应用程序所在的位置非常重要,若是位置不对就扫描不到注解无法加入的IOC容器中

2.@Import({AutoConfigurationImportSelector.class})  springboot完成自己动配置类
源代码:
1.点开@Import({AutoConfigurationImportSelector.class})中的AutoConfigurationImportSelector(
2.可以看见selectImports返回的是一个字符串数组 里面装的就是自动配制类的名字
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
3.点开getAutoConfigurationEntry()方法看他是如何获取自动配置实体类的
4.在getAutoConfigurationEntry() 我们可以看见 获取的配置类的集合 同时也发现许多处理配置类的方法
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
5.点开getCandidateConfigurations  看是如何获取候选配置的
6在getCandidateConfigurations 方法中 我们发现获取配置类的集合
List<String> configurations = SpringFactoriesLoader.loadFactoryNames();
7.点开loadFactoryNames()方法我们就可以看到配置类所在路径
classLoader.getResources("META-INF/spring.factories")
8.在spring-boot-autoconfig/META-INF/spring.factories

总结:
1.通过导入AutoConfigurationImportSelector.class 获取去该类的selectImports ()方法获取自动配置类
autoConfigurationEntry = this.getAutoConfigurationEntry();
2.getAutoConfigurationEntry()该方法提供了 List<String> configurations = this.getCandidateConfigurations()获取了候选配置类 从而将spring-boot-autoconfig/META-INF/spring.factories 中的所有配置读入到list集合中
3.spring-boot-autoconfig/META-INF/spring.factories 都是我们配置类的名字   一共有124个配置类
4.getAutoConfigurationEntry()提供了configurations = this.removeDuplicates(configurations); 移除重复的配置类  重复的0 个
3.checkExcludedClasses(configurations, exclusions);移除我们设定好的配置类 既在SpringBootConfiguration使用exclude()属性进行移除
4.configurations = this.filter(configurations, autoConfigurationMetadata); 通过我们配置的元数据进行过滤一些配置类  过滤之后剩下23个
5 在把过滤后的配置类返回给AutoConfigurationImportSelector 
   return new AutoConfigurationImportSelector.AutoConfigurationEntry(); 
6.根据配置类的名字 利用反射机制加载进来 创建该类的对象并加入到 ioc容器中 加入ioc容器配置类就起里作用
7.之所以被过滤掉 是我们的配置类都有条件的,只有满足这些条件配置类才能够生效
@Configuration() 声明该类是个配置类
@ConditionalOnClass({CacheManager.class})  必须存在CacheManager.class这个类 这个配置类才会生效
@ConditionalOnBean({CacheAspectSupport.class})  ioc必须存在CacheAspectSupport对象  配置类才会生
@ConditionalOnMissingBean(   ioc中存在名字为cacheResolver的对象 这个配置类就不会失效 所以我们自己可以定义个名字与cacheResolver一样的 这个配置类就失效了 可以用自己定义的了
   value = {CacheManager.class},
    name = {"cacheResolver"}
)
也就说只有满足以上三点的配置类才不会被过滤,才能够配置到ioc容器中。
8.所以我们需要让我们自己想要的配置类生效的或就满足上面三个条件就springboot可以自动的配置了。
7.@EnableConfigurationProperties({CacheProperties.class})  可以查看CacheProperties中的默认属性我们可以根据这个前缀 prefix = "spring.cache"来修改配置类中的默认属性


 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值