轻松把握SpringBoot智能装配-从入门到精通 (轻松把握的成语)
一.何为智能装配
智能装配是SpringBoot的外围性能,关键是让开发者尽或者少的关注一些基础化的Bean的性能,实践上成功的上班是如何智能将Bean装载到Ioc容器中。
在SpringBoot中假构想要引入一个新的模块,例如名目中想经常使用缓存,只要要做以下几步即可。
1、在pom.xml文件中引入spring-boot-starter-data-redis相关的jar包
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>
2、在lication.properties文件中参与Redis相关的性能
spring.redis.host=127.0.0.1spring.redis.port=6379
3、在代码中援用Redis缓存的操作类
@AutowiredprivateRedisTemplate<String,String>redisTemplate;
为什么RedisTemplate可以被间接注入,它是什么时刻参与到Ioc容器中的,这都是智能装配的功劳,咱们一同来看一下。
二.智能装配环节
1、@EnableAutoConfiguration剖析
SpringBoot名目启动类上有@SpringBootApplication这样一个注解,它承袭了@EnableAutoConfiguration,关键作用是协助Springboot运行把一切合乎条件的性能类都加载到以后SpringBoot创立并经常使用的Ioc容器中。
这个注解关键由两局部组成
@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration{...}
1.1@AutoConfigurationPackage
@AutoConfigurationPackage指定SpringBoot扫描的包范围,关键逻辑在AutoConfigurationPackages#register方法中。
该方法有两个参数registry和packageNames,在断点中发现registry实践上就是DefaultListableBeanFactory实例,packageNames的值自动是启动类包所在的门路,在这里将@AutoConfigurationPackage指定的包门路参与到DefaultListableBeanFactory,在后续Ioc容器扫描时将其加载出来。
图片
1.2AutoConfigurationImportSelector.class
AutoConfigurationImportSelector关键是成功importSelector方法来成功基于灵活Bean的加载性能,咱们定位到importSelector方法看一下外面的逻辑。
@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){if(!isEnabled(annotationMetadata)){returnNO_IMPORTS;}//1、从性能文件spring-autoconfigure-metadata.properties中加载智能装配候选规定AutoConfigurationMetadataautoConfigurationMetadata=AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);//2、失掉@SpringBootApplication上性能的属性值AnnotationAttributesattributes=getAttributes(annotationMetadata);//3、经常使用SpringFactoriesLoader加载classpath门路下META-INFspring.factories中//经过key=org.springframework.boot.autoconfigure.EnableAutoConfiguration失掉候选类List<String>configurations=getCandidateConfigurations(annotationMetadata,attributes);//4、去除重复值configurations=removeDuplicates(configurations);//5、失掉exclude属性值,将exclude中的值扫除掉Set<String>exclusions=getExclusions(annotationMetadata,attributes);checkExcludedClasses(configurations,exclusions);configurations.removeAll(exclusions);//6、审核候选性能类上的注解@ConditionalOnClass,假设要求的类不存在,则这个候选类会被过滤不被加载configurations=filter(configurations,autoConfigurationMetadata);fireAutoConfigurationImportEvents(configurations,exclusions);returnStringUtils.toStringArray(configurations);}
第一步和第三步逻辑中触及到两个十分关键的文件spring-autoconfigure-metadata.properties、spring.factories
图片
SPI,全称为ServiceProviderInterface,是一种服务发现机制。它经过在ClassPath门路下的META-INF/services文件夹查找文件,智能加载文件里所定义的类。这一机制为很多框架裁减提供了或者,比如在Dubbo、JDBC中都经常使用到了SPI机制。
图片
2、@Import剖析
在@EnableAutoConfiguration剖析中,两种加载Bean到Ioc容器的模式,他们都是经过@import引入,这里咱们来剖析一下@import是在哪里启动加载的。
2.1@import3种经常使用模式
@Import(PersonConfig.class)@ConfigurationpublicclassPersonConfiguration{}
@Import(TestImportSelector.class)@ConfigurationpublicclassImportTestConfig{}
publicclassTestImportSelectorimplementsImportSelector{@OverridepublicString[]selectImports(AnnotationMetadataimportingClassMetadata){returnnewString[]{"com.example.service.TestService"};}}
@Import(TestImportBeanDefinitorSelector.class)@ConfigurationpublicclassImportBeanDefinitionTestConfig{}
publicclassTestImportBeanDefinitorSelectorimplementsImportBeanDefinitionRegistrar{@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){AbstractBeanDefinitionbeanDefinition=BeanDefinitionBuilder.rootBeanDefinition(Person.class).getBeanDefinition();registry.registerBeanDefinition("person",beanDefinition);}}
2.2@Import成功原理
@Overridepublicvoidrefresh()throwsBeansException,IllegalStateException{//....省略n行代码//1.beanFactory后置处置逻辑,在这个方法里加载ConfigurationClassPostProcessorinvokeBeanFactoryPostProcessors(beanFactory);//2.注册bean后置处置逻辑registerBeanPostProcessors(beanFactory);//...省略n行代码//3.实例化非懒加载的bean,并参与到Ioc容器中finishBeanFactoryInitialization(beanFactory);//....省略n行代码}
@NullableprotectedfinalSourceClassdoProcessConfigurationClass(ConfigurationClassconfigClass,SourceClasssourceClass)throwsIOException{//...省略n行代码//加载@Import注解,递归解析,失掉导入的性能类processImports(configClass,sourceClass,getImports(sourceClass),true);//...省略n行代码}
privatevoidprocessImports(ConfigurationClassconfigClass,SourceClasscurrentSourceClass,Collection<SourceClass>importCandidates,booleancheckForCircularImports){//...省略n行代码if(candidate.isAssignable(ImportSelector.class)){//1.成功了ImportSelector接口的类在@Import中援用逻辑Class<?>candidateClass=candidate.loadClass();ImportSelectorselector=BeanUtils.instantiateClass(candidateClass,ImportSelector.class);ParserStrategyUtils.invokeAwareMethods(selector,this.environment,this.resourceLoader,this.registry);if(this.deferredImportSelectors!=null&&selectorinstanceofDeferredImportSelector){this.deferredImportSelectors.add(newDeferredImportSelectorHolder(configClass,(DeferredImportSelector)selector));}else{String[]importClassNames=selector.selectImports(currentSourceClass.getMetadata());Collection<SourceClass>importSourceClasses=asSourceClasses(importClassNames);processImports(configClass,currentSourceClass,importSourceClasses,false);}}elseif(candidate.isAssignable(ImportBeanDefinitionRegistrar.class)){//2.成功了ImportBeanDefinitionRegistrar接口的类在@Import中援用逻辑Class<?>candidateClass=candidate.loadClass();ImportBeanDefinitionRegistrarregistrar=BeanUtils.instantiateClass(candidateClass,ImportBeanDefinitionRegistrar.class);ParserStrategyUtils.invokeAwareMethods(registrar,this.environment,this.resourceLoader,this.registry);configClass.addImportBeanDefinitionRegistrar(registrar,currentSourceClass.getMetadata());}else{//3.普通类间接在@Import中援用逻辑this.importStack.registerImport(currentSourceClass.getMetadata(),candidate.getMetadata().getClassName());processConfigurationClass(candidate.asConfigClass(configClass));}//...省略n行代码}
总结一下就是如下的方法链调用
refresh()=>invokeBeanFactoryPostProcessors()=>postProcessBeanDefinitionRegistry()=>parse()=>doProcessConfigurationClass()=>processImports()
3、启动类何时参与到Ioc容器
前面咱们剖析了智能装配的关键逻辑,那么SpringBoot启动类又是如何参与到Ioc容器中的呢?
3.1prepareContext()中的load()方法
privatevoidprepareContext(ConfigurableApplicationContextcontext,ConfigurableEnvironmentenvironment,SpringApplicationRunListenerslisteners,ApplicationArgumentsapplicationArguments,BannerprintedBanner){//...省略n行代码//加载启动类,将启动类注入到Ioc容器中load(context,sources.toArray(newObject[0]));//...省略n行代码}
图片
总结一下就是如下的方法链调用
run()=>prepareContext()()=>load()=>parse()=>register()
4、智能装配全体流程
基于以上3块的剖析咱们可以失掉如下一个关于智能装配的流程图
图片
三.总结
学习源码的环节中假设不了解源码的全体思绪,间接看代码会迷失在源码的陆地中。要了解代码的全体头绪,以总-分-总的模式去学习,学会舍弃局部有关的代码,才干高效的浏览和学习源码,从中吸取到代码的精髓所在,优化自己的编程才干。
参考资料:
学妹想学SpringBoot,连夜整理一篇SpringBoot入门最详细教程笔记
凭借开箱即用,远离繁琐的配置等特性,Spring Boot 已经成为 Java 开发者人人必学必会的开源项目。那么开发者该如何快速上手Spring Boot 呢?
那请问Spring Boot 到底是啥?Spring Boot是Spring框架的扩展和自动化,它消除了在Spring中需要进行的XML(EXtensible Markup Language)文件配置(若习惯XML配置,则依然可以使用),使得开发变得更快、更高效、更自动化。
微服务:每一个功能元素最终都是一个可独立替换和独立升级的软件单元。
在maven 的配置文件的profiles标签添加以下配置:
把maven整合到idea。
项目目录:
HelloWorldMainApplication:
HelloController:
运行结果:
打开浏览器访问:
1、我们在文件中假如以下代码:
2、然后,我们将应用打包
3、然后再target文件夹下就可以看到
4、复制到桌面(随便哪,个人选择),打开cmd窗口,切换到jar包所在位置,我的是桌面,然后输入: java -jar ,运行效果如下。
5、打开浏览器访问:,同样可以看到HelloWord
这样的部署就变得十分简单了。
小伙伴们,帮忙一键三连呀
题外话,我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在Java学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多程序员朋友无法获得正确的资料得到学习提升
故此将并 将重要的Java进阶资料包括并发编程、JVM调优、SSM、设计模式、spring等知识技术、阿里面试题精编汇总、常见源码分析等录播视频免费分享出来,需要领取的麻烦 评论区领取
springboot自动装配原理面试回答是什么?
SpringBoott自动装配原理主要解决了传统spring的重量级xml配置Bean.实现了自动装配;所以,我们也常在面试中被问到SpringBoot是如何实现自动装配。
springboo的介绍
SpringBoot基于Spring4.0设计,不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程。
另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。SpringBoot框架中还有两个非常重要的策略:开箱即用和约定优于配置,开箱即用,Outofbox,是指在开发过程中。
通过在MAVEN项目的pom文件中添加相关依赖包,然后使用对应注解来代替繁琐的XML配置文件以管理对象的生命周期。
这个特点使得开发人员摆脱了复杂的配置工作以及依赖的管理工作,更加专注于业务逻辑。约定优于配置,Convention over configuration,是一种由SpringBoot本身来配置目标结构。
免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。