我们大部分Java程序员的日常工作基本就是做业务开发,俗称crudboy。作为一个渣男,你有这些烦恼吗?随着业务的迭代和新功能的加入,代码越来越臃肿,可维护性越来越低。渐渐变成了一座屎山。遇到了一些framework层的问题,不知道怎么解决。我被要求在面试中使用它。不知道框架、中间件原理、源码层怎么回答。写了5年代码,感觉自己的技术没有达到预期的提升。如果你有以上的烦恼,我想一个优秀框架的源码会是一个不错的选择。升降方式。通过查看源码,我们可以了解到行业大咖们优秀的设计理念、编码风格、设计模式的运用、高效数据结构算法的运用、魔鬼细节的巧妙运用等等。这些东西对于帮助我们成为一名优秀的工程师来说是必不可少的。如果打算看源码,推荐先看Spring、Netty、Mybatis、JUC包。Spring扩展我们知道Spring提供了很多扩展点,大多数第三方框架都是基于这些扩展点集成Spring的。因此,熟练掌握Spring的扩展,可以让我们在阅读源码时快速找到入口,然后断点调试,一步步进入框架核心。这些扩展包括但不限于以下接口:BeanFactoryPostProcessor:在Bean实例化之前修改BeanDefinitionBeanPostProcessor:在Bean初始化前后对Bean进行一些修改和封装增强,比如返回代理对象Aware:a实现接口及其子接口的标记接口类会接收来自Spring的通知回调,赋予Spring框架一定的能力,如ApplicationContextAware、EnvironmentAware等。ApplicationContextInitializer:在上下文准备阶段,在容器刷新前做一些初始化工作,比如我们常用的配置中心客户端。initializer在容器刷新前将配置从远程拉取到本地,然后封装成一个PropertySource放到Environment中使用。ApplicationListener:Spring事件机制,监听具体的应用事件(ApplicationEvent),观察者模式的一种实现FactoryBean:使用自定义Bean创建逻辑(Mybatis、Feign等)ImportBeanDefinitionRegistrar:定义@EnableXXX注解,导入一个ImportBeanDefinitionRegistraron注解,将BeanDefinition注册到容器中InitializingBean:Bean初始化时,会调用一些初始化逻辑ApplicationRunner/CommandLineRunner:容器启动后,会回调并进行一些初始化工作。上面列举了几个常用的接口,但是Spring的扩展远不止这些,还有很多扩展接口可以自己去学习。SpringSPI机制在说下一个内容之前,先说说Spring中的SPI机制。Spring中的SPI主要是使用META-INF/spring.factories文件实现的。文件内容由多个k=list(v)格式组成,如:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.dtp.starter.adapter.dubbo.autoconfigure.ApacheDubboTpAutoConfiguration,\com.dtp。starter.adapter.dubbo.autoconfigure.AlibabaDubboTpAutoConfigurationorg.springframework.boot.env.EnvironmentPostProcessor=\com.dtp.starter.zookeeper.autoconfigure.ZkConfigEnvironment复制这些代码spring.factories文件可能位于多个jar包中。Spring容器启动时,会通过ClassLoader.getResources()获取这些spring.factories文件的完整路径。然后遍历路径以字节流的形式读取所有的k=list(v)并封装成一个Map,key是接口的全限定类名,value是接口的全限定类名列表所有实现类。上面提到的加载操作都封装在了SpringFactoriesLoader类中。这个类非常简单。它提供了三种加载方式,一种实例化方式,一种缓存属性。第一次加载的数据会保存在缓存中,以供后续使用。SpringBoot的核心点上面说的SPI其实就是我们SpringBoot自动组装的核心。什么是自动装配?自动装配对应于手工装配。在SpringBoot之前,我们使用Spring都是采用手工组装的方式。在使用第三方功能时,我们需要导入该功能所依赖的所有包,并测试确保这些导入包的版本兼容。然后在XML文件中配置大量的标签,非常繁琐。后来在Spring4中引入了JavaConfig功能,使用@Configuration+@Bean来代替XML配置。虽然对开发友好了很多,但是这些模板配置代码还是很繁琐,会浪费很多配置时间。Java的重量级,可能就是这时候给人留下的印象。在这样的背景下,SpringBoot出现了,SpringBoot可以说是稳住了Java的地位。SpringBoot提供了自动组装功能。自动组装简单来说就是将某些功能(如web相关、redis相关、logging相关等)进行封装,统一管理依赖包版本,约定相关功能bean的组装规则。使用用户只需要引入一个依赖,通过一些注解或者简单的配置就可以使用第三方组件提供的功能。在SpringBoot中,这样的功能组件有个好听的名字叫starter。如spring-boot-starter-web、spring-boot-starter-data-redis、spring-boot-starter-logging等。在starter中使用@Configuration+@Bean+@ConditionalOnXXX等注解来定义Bean被注入到Spring中,然后在spring.factories文件中配置为org.springframework.boot.autoconfigure.EnableAutoConfiguration的实现,完成自动组装。具体的组装过程如何?其实也很简单。基本就是Spring里面的知识,没什么新鲜的。它主要依赖@EnableAutoConfiguration注解,它会导入一个AutoConfigurationImportSelector。看继承关系。该类继承自DeferredImportSelector。主要方法是getAutoConfigurationEntry()protectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata){//1if(!isEnabled(annotationMetadata)){returnEMPTY_ENTRY;}AnnotationAttributes属性=getAttributes(annotationMetadata);//2List
