SpringBoot自动装配核心源码

1.从Spring的IOC到SpringBoot的自动配置原理

SpringBoot是一个脚手架,在spring的基础上构建,帮我们配置好了很多bean,管理bean还是由Spring IOC来做的。不管是配置xml还是javaconfig还是会经过spring变成BeanDefnition(xml中的bean的lazy,scope,autowire,class等定义信息由这个类的各个属性装载,class="com.xx.User"最后通过反射加载到spring的单例池中),再经过BeanFactory到ioc容器

2.DeferredlmportSelector对Bean加载顺序的影响

假如一个spring集成了10几个项目(mybatis,springmvc等),现在要去掉一个mybatis,spring做起来就很不方便,热插拔和扩展这方面。那么在应用层面要怎么做呢? javaconfig(@Bean,@Import (可以导入不在扫描范围内的类注册为bean),@Component(导入在扫描范围内的类),@EnableXXX(里又有@Import) ),其实@Import就够了。

@Import有几种用法?1.@Import(类)2.@Import(实现lmportSelector接口的类),不能控制顺序3.@Import(实现lmportBeanDefinitionRegistrar的类)。大致就这3种

实现lmportSelector接口的类不能控制顺序(假如现在有一个DataSource类加了@Bean,实现lmportSelector接口的类里又出现这个MybatisAutoConfiguration类,加了@ConditionalOnBean(DataSource.class)修饰,ConditionalOnBean的意思是希望已经有DataSource这个BeanDefinition出现了才可以注册,因为lmportSelector里一般是默认配置的类,而用@Bean修饰的是自定义的类,不希望默认配置的顺序在后。但是它不能保证@Bean修饰的类顺序在前),所以出现了变种DeferredlmportSelector。Deferred(延迟的意思),就是说用这个注解修饰,bean的顺序就是最后解析的。

DeferredlmportSelector除了延迟的特性,还有一个分组的特性,组1(ABC3个类)组2(DEF),可以让F排在组2的前面(FDE),实现DeferredlmportSelector.Group。比如自己的配置组(DataSource...)在BeanDefinitionMap中排在springboot默认配置组前(MybatisAutoConfiguration等等其他bean),springboot组怎么排序也不用影响到自定义的配置。

Springboot通过@lmport导入@DeferredlmportSelector(保证顺序在最后,分组),可以批量读取扫描所有jar包中的spring.factories的bean,组成一个list,返回给spring的BeanDefinitionMap管理了。

3.SpringBoot自动配置源码深入分析

启动类上@SpringBootApplication上面有@EnableAutoConfiguration,@EnableAutoConfiguration上面@Import({EnableAutoConfigurationImportSelector.class}),EnableAutoConfigurationImportSelector继承的类实现了DeferredlmportSelector接口

spring.factories中EnableAutoConfiguration=集成的多个三方的bean,某个项目可能只需要几个,那么它是怎么区分的呢

 Springboot启动时它就把配置类读取到缓存中了,拿到所有的自动配置类,排除掉重复的类和@EnableAutoConfiguration注解exclude中的类,过滤AutoConfigurationImportFilters中的类,开始分组排序(@Order/@AutoConfigureAfter等注解),但是只有在pom中导入了starter的才会生效。

还有一些是主动引入的jar包,也是有自己spring.factory,里面也有自己的自动配置类,比如nacos

 

4.如何在自动配置类上进行定制扩展

第一种就是在全局application.properties里配置,第二种就是配置@Bean覆盖掉自动配置类中默认的属性

在配置文件中debug=true启动后就能看到生效的配置类,比如AopAutoConfiguration,进入到里面可以看到@ConditionalOnProperty这个注解的属性matchIfMissing就是说如果没有在配置文件中配spring.aop.auto = true,他默认也是true。@ConditionalOnClass(Advice.class)这个是说需要类路径中有这个类,也就是引用了Advice切面会生效,以及下面代理用的是哪种方式,默认是CglibAutoProxyConfiguration

 

5.实现自定义Starter完成自动配置

springboot没有mybatis的自动配置,所有mybatis就自定义了spring-boot-starter-web,Starter就是将一个个自动配置类引入应用,集成一些自己需要的如SqlSessionFactory。一般名字xxx-starter-xx,springboot就是spring-boot-starter-web,spring-boot-starter-aop等

 

 自定义需要建一个项目里面有两个子项目,一个autoconfigure,一个starter,下面是autoconfigure的部分pom配置,starter是个空项目,依赖autoconfigure即可。

@Configuration
@ConditionalOnProperty(value = "tuling.hello.name")
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnClass(StrUtil.class)
public class HelloAutoConfitguration {

    @Autowired
    HelloProperties helloProperties;

    @Bean
    public IndexController indexController(){
        return new IndexController(helloProperties);
    }
}

 install 父模块上传到本地maven仓库,否则在starter项目中install会报错Could not resolve dependencies for project spring-boot-autoconfigure。在自己项目中引入这个starter,符合自定义的自动配置类上面的条件就能生效了,需要引入StrUtil类并且配置属性tuling.hello.name="xx"才能生效

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值