当前位置: 首页 > news >正文

新浪网站怎么做推广网站内容策划

新浪网站怎么做推广,网站内容策划,可以做外贸私单的网站,linux网站建设今天#xff0c;聊聊SpringBoot的源码#xff0c;本博客聊的版本为v2.0.3.RELEASE。目前SpringBoot的最新版为v3.3.2#xff0c;可能目前有些公司使用的SpringBoot版本高于我这个版本。但是没关系#xff0c;因为版本越新#xff0c;新增的功能越多#xff0c;反而对Spri…        今天聊聊SpringBoot的源码本博客聊的版本为v2.0.3.RELEASE。目前SpringBoot的最新版为v3.3.2可能目前有些公司使用的SpringBoot版本高于我这个版本。但是没关系因为版本越新新增的功能越多反而对SpringBoot源码的研究带来更多的困难我觉得没必要刻意追求最新只要掌握其核心流程即可万变不离其宗。另外前面我花了大量的时间一共写了六篇博客也是为了讲SpringBoot框架做铺垫Spring/SpringMVC的原理如果没看的话建议先看这部分的博客(《Spring源码深度解析(上)、《SpringMVC源码深度解析(上)》)不然直接看SpringBoot源码会有一定难度。因为我理解的SpringBoot框架是对Spring FrameWork框架的进一步封装。OK话不多说进入正题。 先看看项目的层级目录 依赖也很简单如下 ?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-project/artifactIdversion2.0.3.RELEASE/version/parentmodelVersion4.0.0/modelVersionartifactIdmy-spring-boot/artifactIdpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.target/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdversion2.0.3.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdversion2.0.3.RELEASE/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactIdversion2.0.3.RELEASE/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.24/version/dependency/dependencies/project 使用过SpringBoot框架的朋友都知道SpringBoot会有一个启动类启动类是被SpringBootApplication注解修饰的。看看App.class的代码 那就以SpringApplication这个类最为切入点讲解。先看SpringBootApplication注解代码如下 可以看出SpringBootApplication注解也是可以添加包扫描路径的最终添加的包扫描路径会设置到ComponentScan注解中的scanBasePackages或者scanBasePackageClasses属性中去。但是我们一般不会指定默认扫描的包路径为App类所在的包及其子包。然后在SpringBootApplication注解注解上还添加了几个注解分别是ComponentScan、SpringBootConfiguration、EnableAutoConfiguration等。ComponentScan自不必说SpringBootConfiguration注解实际上又是被Configuration注解修饰的如果把SpringBootConfiguration注解替换成Configuration注解也是没有任何问题的。 因此被SpringBootApplication注解修饰的类可以直接当配置类使用也就是可以在类中添加其它类到Spring容器中。重点来了就是EnableAutoConfiguration注解这是SpringBoot实现自动装配的关键代码如下 可以看出EnableAutoConfiguration注解可以排除一些类除此之外这个注解上面也被其他注解所修饰分别是AutoConfigurationPackage注解和Import注解。代码中的注释对AutoConfigurationPackage注解我说的很清楚作用就是往Spring容器中注入BasePackages对象该类存有扫描的包信息用于其他框架整合SpringBoot的时候方便获取到这个v包进行它自己的扫描需要这样操作的框架还挺多的如Mybatis、Dubbo、Open Feign等。当然其他框架用不用这个类是它们的事但是SpringBoot有提供这样的方式。 再看看Import注解熟悉Spring框架的朋友应该对这个注解很熟悉它的作用是向Spring容器中注入Import注解配置的Class。看看AutoConfigurationImportSelector类代码如下 可以看出AutoConfigurationImportSelector实现了DeferredImportSelector、BeanClassLoaderAware、ResourceLoaderAware、BeanFactoryAware、EnvironmentAware等接口Spring框架在初始化AutoConfigurationImportSelector的时候会多次调用回调方法比如给AutoConfigurationImportSelector设置ConfigurableListableBeanFactory、Environment、ClassLoader、ResourceLoader等对象。其中DeferredImportSelector接口很重要根据这个接口的特点当Spring在解析配置类的时候当解析完这一轮配置类后才回调用DeferredImportSelector#selectImports()方法由于有着一个延迟解析的特点才能实现这样一个功能比如Servlet容器有很多种如Tomcat、Jetty、Undertow等默认使用Tomcat作为Servlet容器如果此时开发人员不想用Tomcat想用Jetty那应该怎么做呢很简单引入Jetty的依赖排除Tomcat相关依赖即可。这里涉及到ServletWebServerFactoryConfiguration类代码如下 除了我刚刚说的引入Jetty的依赖再排除Tomcat相关依赖可以改成使用Jetty服务器还有一个方法也可以做到即不用排除Tomcat的依赖只需要再引入Jetty的依赖在自己的配置类中添加JettyServletWebServerFactory即可。因为ServletWebServerFactoryConfiguration这个配置类是Spring在解析完程序员自定义的配置类后再解析的因此通过ConditionalOnMissingBean注解进行判断的时候会发现此时Spring容器中已经有了之前注入的JettyServletWebServerFactory对象了因此ServletWebServerFactoryConfiguration中配置三个ServletWebServerFactory对象都不会注入到Spring容器中最后调用ServletWebServerFactory#getWebServer()方法得到的只有JettyWebServer代码如下 因此可以知道AutoConfigurationImportSelector实现DeferredImportSelector接口的作用就是保证程序员的配置大于默认配置当然讲到这里其实还不是SpingBoot的自动装配自动装配的话还是要看AutoConfigurationImportSelector#selectImports()方法代码如下 再看看AutoConfigurationImportSelectorget#CandidateConfigurations()方法看看它是如何获取配置类的代码如下 可以看出上面的逻辑是通过ClassLoader读取classpath下的META-INF/spring.factories文件获取文件中的内容看看spring.factories如下 其中有一个EnableAutoConfiguration类的全限定名而且确实方法中也传入了EnableAutoConfiguration类的全限定名因此可以猜到程序读取spring.factories文件并通过EnableAutoConfiguration类的全限定名作为Key获取对用的value也就是截图中的一大堆类的全限定名并返回这就是所有待解析的配置类。其中也不乏我们熟悉的类如RabbitAutoConfiguration、AopAutoConfiguration、ElasticsearchDataAutoConfiguration等等。那是不是把这些配置类全部返回并进行加载解析就行了呢当然不行准确的说是没必要因为这些配置类都是要有相关的依赖才会起作用因此需要过滤当然如果通过SpringBootApplication配置排除配置类或者配置类名这种也需要过滤。 以上就是SpringBoot自动装备的原理。如果我们自己要写一个工具怎么与SpringBoot整合呢其实很简单自己写一个项目在META-INF目录下建一个spring.factories文件目录为 在该文件中内容为org.springframework.boot.autoconfigure.EnableAutoConfiguration你的配置的全限定名。如果有多个配置类就用,隔开。这样在pom文件中引入你写的工具的依赖SpringBoot就会加载这个配置类再配合配置上加的条件注解即可。 回到App类中看看main方法 在该方法中核心的类是SpringApplication先看看它的有参构造方法传入的是App.class代码如下 将传入的App.class存入LinkedHashSet并赋值给primarySources属性。然后调用SpringApplication#deduceWebApplicationType()推断应用类型代码如下 再调用SpringApplication#getSpringFactoriesInstances()方法传入ApplicationContextInitializer.class加载ApplicationContextInitializer.class接口的实现类代码如下 并将获取到的ApplicationContextInitializer对象的集合赋值给SpringApplication的initializers属性代码如下 同理从spring.factories中获取到所有ApplicationListener对象的集合赋值给SpringApplication的listeners属性中。最后调用SpringApplication#deduceMainApplicationClass()方法推断主类代码如下 最终获取到的也是App.calss并赋值给SpringApplication的mainApplicationClass属性。 以上就是SpringApplication的有参构造方法。这也这只是完成了SpringApplication初始化工作但是要让服务跑以来核心的就是调用SpringApplication#run(String[] args)方法代码如下 其实我的注释写的很详细的不过我还是带着大家看看。首先是看看SpringApplication#getRunListeners()方法代码如下 还是通过通过spring.factories文件获取SpringApplicationRunListener对象的集合实际上只有一个实现类就是 EventPublishingRunListener在创建这个对象的时候会调用它的有参构造传入 SpringApplication对象有参构造的代码为 最终将EventPublishingRunListener对象在设置到SpringApplicationRunListeners对象中后续在进行时间发布的时候调用的是SpringApplicationRunListeners的某些方法代码如下 回到SpringApplication#run()方法接着就是调用SpringApplicationRunListeners#starting()方法发布ApplicationStartingEvent调用ApplicationListener#onApplicationEvent()方法调用之前会先判断哪些ApplicationListener对象是对ApplicationStartingEvent事件“感兴趣”的。这里没有太多好说的就不说了继续往下看再调用SpringApplication#prepareEnvironment()这里是处理环境变量配置就是在这个方法中解析读取的需要重点看看代码如下 先看看SpringApplication#getOrCreateEnvironment()方法代码如下 看看StandardServletEnvironment的类继承图如下 看看父类的构造发现AbstractEnvironment父类构造中有做一些初始化的操作代码如下 到这里可以知道此时在环境变量中应该设置了四种属性顺序(顺序代表着优先级)分别是StubPropertySource(servletConfigInitParams)、StubPropertySource(servletContextInitParams)、MapPropertySource(systemProperties)、SystemEnvironmentPropertySource(systemEnvironment)只不过前两个此时还没有任何值毕竟还没有设置值。打断点看看我说的是否正确 要想获取main方法中的args参数需要先设置在Idea中设置设置如下 可以知道最终通过main方法传入的args参数封装成SimpleCommandLinePropertySource对象并放入环境变量属性的最前面此时环境变量有五种属性了。打断点看看 再看看SpringApplication#configureProfiles()方法代码如下 重点看看SpringApplicationRunListeners#environmentPrepared()方法代码如下 看这个事件名可以猜到是处理配置相关的继续往下看代码如下 这里我可以明确的告诉你调用的是ConfigFileApplicationListener#onApplicationEvent()方法(我看过SpringBoot v2.6的版本这个版本中没有使用ConfigFileApplicationListener来解析配置文件了最低是什么版本就没有再使用ConfigFileApplicationListener类了这我就不确定了)这个方法会处理配置文件该方法的代码如下 可以知道会创建RandomValuePropertySource(random)对象放在SystemEnvironmentPropertySource(systemEnvironment)后面到目前为止环境变量一共有六种属性了打断点看看代码如下 OK再看看Loader#Loader()方法代码如下 再看看Loader#initializeProfiles()方法 可以知道此时在profiles中有两个对象也是个空的Set对象另一个是Profile(default)。回到Loader#Loader()方法继续往下看接着就是遍历profiles对象代码如下 核心是调用重载方法 Loader#Loader()代码如下 因此从源码可以知道环境变量设置spring.config.location、spring.config.additional-location可以指定读取文件的路径如果没有设置的话默认读取的路径为file:./config/ 、file:./、classpath:/config/、classpath:/ 等四个路径(顺序即为读取路径的优先级)。并且设置 spring.profiles.active可以设置文件后缀如设置为 dev最后读取的文件为xx-dev。 然后就是对这四个路径进行遍历判断那个路径下有配置文件。除了知道文件路径外还要知道读取的文件名叫什么这个也有默认值当然也可以通过配置去修改默认的文件名代码如下 有了路径和文件名就可以准备读取了代码如下 看看PropertySourceLoader是如何赋值的代码如下 可以知道也是从spring.factories文件中读取PropertySourceLoader接口的实现类并实例化一共有两个分别是PropertiesPropertySourceLoader 和 YamlPropertySourceLoader。前者用于解析xml和propeties后缀的文件后者解析yml和yaml后缀的文件如下 继续往下看代码如下 看看Loader#loadDocuments()方法代码如下 到这里就行了感兴趣的可以自己研究回到Loader#load()方法代码如下 调用consumer#accept()方法也就是前面传入的λ表达式即 到目前为止解析的还是application由于我在application.yml配置了profile因此还会继续读取 回到Loader#load()方法由于在前面已经读取到application.yml中设置的dev了并放入Loader的profiles属性中而且还是在遍历profiles因此最终会解析application-dev.yml文件代码如下 读取配置的逻辑一样这里不再赘述到现在为止读取的配置还只是存在Loader的loaded属性中需要放如环境变量中也就是调用下面的代码代码如下 在读取配置的时候会多次调用Collections.reverse()方法改变顺序其实这就是配置优先级的关键继续往下看 到现在为止环境变量中已经有八个配置了其中application-dev.yml的配置在application.yml之前。如果通过环境变量取值的话就是按照这个顺序来取值的也就是说只有前面七个配置中找不到才会到第八个配置中找到目前为止我觉得SpringBoot配置读取这块应该是讲的很详细了。 回到SpringApplication#run()方法继续往下看代码如下 再看看SpringApplication#prepareContext()方法代码如下 看看BeanDefinitionLoader#load()方法代码如下 回到SpringApplication#run()方法再看看SpringApplication#refreshContext()方法代码如下 看看它的继承关系图 AbstractApplicationContext#refresh()方法有多重要想必就不用我多说了吧这块的代码在我之前的博客《Spring源码深度解析(上)》讲的很详细了有兴趣的可以看看其中有两个方法即onRefresh()方法和finishRefresh()方法需要我说一下先看看onRefresh()方法代码如下 其中ServletWebServerApplicationContext#initPropertySources()方法会将ServletContext属性值设置到环境变量中代码如下 再看ServletWebServerApplicationContext#createWebServer()方法代码如下 再看看finishRefresh()方法代码如下 最后再回到SpringApplication#run()方法看看剩下的代码如下 到这里位置SpringBoot框架的源码算是讲完了我个人觉得应该是讲的很全面的如果在讲解的过程中有漏讲或者讲错的欢迎指出感谢~
http://www.w-s-a.com/news/485668/

相关文章:

  • 视频制作素材网站wordpress mysql 被删
  • 静态网站 模板公司一般都用什么邮箱
  • 做网站效果图是用ps还是ai泰安人才网最新招聘信息2022年
  • 免费建站网站一级大录像不卡在线看网页郑州网站关键
  • 做网站 然后百度推广哈尔滨建筑网
  • 章丘营销型网站建设网站测评必须做
  • 营销者网站怎么把网站黑了
  • 律师事务所手机网站校园网站设计
  • 网站案例展示分类网站响应速度优化
  • 风景网站的制作网站ip地址查询域名
  • 怎样看网站是谁做的马鞍山什么房产网站做的好
  • 西安推荐企业网站制作平台软装设计方案ppt
  • 网站静态页模板专业网站设计开发公司
  • 手机免费在线搭建网站短网址生成防红
  • 天津网站设计网站制作如何新建wordpress
  • 山东省建设备案网站审批国际新闻最新消息10条简短
  • 成都市建设网扬尘监控网站短域名转换
  • 怎么做手机网站潍坊建设银行网站
  • 做网站分什么软件品牌设计培训
  • 太原网站设计排名设计本装修效果图
  • 网站个人中心模板石家庄网站系统开发
  • 优秀的电子商务网站教育公司网站建设文案
  • 网站开发市场成本网站链接推广工具
  • 猪八戒做网站排名常州seo博客
  • wordpress 网站遭篡改如何优化公司的网站
  • 汉中公司做网站网站建设的风格设置
  • 网站建议怎么写怎么做网页连接
  • 站长工具seo综合查询下载安装软件平台搭建包括哪几个方面
  • 做网站怎么存放视频支付功能网站建设
  • 庆阳手机网站设计兰州网站的优化