本文共 6729 字,大约阅读时间需要 22 分钟。
org.springframework.boot spring-boot-starter-parent 2.2.11.RELEASE
org.springframework.boot spring-boot-dependencies 2.2.11.RELEASE ../../spring-boot-dependencies
我们再点进行就会发现秘密
这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;
在SpringBoot导入依赖默认是不需要写版本, 它会默认匹配自带的版本号;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;
在pom.xml中还有一个最重要的web启动器
org.springframework.boot spring-boot-starter-web
springboot-boot-starter-xxx:就是spring-boot的场景启动器
spring-boot-starter-web:当我们创建SpringBoot项目选择了web依赖的时候, 系统就帮我们导入了web启动器正常运行所依赖的组件;
SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可
//通过这个注解, 标注这个类是一个SpringBoot的应用@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { //启动SpringBoot SpringApplication.run(DemoApplication.class, args); }}
@Target({ ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan( excludeFilters = { @Filter( type = FilterType.CUSTOM, classes = { TypeExcludeFilter.class}), @Filter( type = FilterType.CUSTOM, classes = { AutoConfigurationExcludeFilter.class})})
@ComponentScan
这个注解在Spring中很重要 ,它对应XML配置中的元素。作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中@SpringBootConfiguration
作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;我们继续进去这个注解查看
@Target({ ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Configurationpublic @interface SpringBootConfiguration { @AliasFor( annotation = Configuration.class ) boolean proxyBeanMethods() default true;}
@Target({ ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface Configuration { @AliasFor( annotation = Component.class ) String value() default ""; boolean proxyBeanMethods() default true;}
里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用的时候去加载一些配置文件!
我们回到 SpringBootApplication 注解中继续看。
有一个 @EnableAutoConfiguration 我们顾名思义这应该是实现自动装配的配置注解, @EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效, 我们点进去看看
@Target({ ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import({ AutoConfigurationImportSelector.class})public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class [] exclude() default { }; String[] excludeName() default { };}
@Import({ Registrar.class})public @interface AutoConfigurationPackage { }
@import :Spring底层注解@import , 作用就是让Spring识别给容器中导入一个组件
Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器
这个分析完了,退到上一步,继续看
@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:
进入这个类后我们更具方法名字很容易判断出这个类是在干什么, 若果想要知道更多可以继续点进行看, 但是我们会发现一个很重要的方法 getAutoConfigurationEntry 这个方法是获得自动配置的入口, 里面有一个方法 getCandidateConfigurations 获取候选配置
我们进入 getCandidateConfigurations 获取候选配置这个方法
我们再进去SpringFactoriesLoader 加载器中
@Configuration( proxyBeanMethods = false)@ConditionalOnWebApplication( type = Type.SERVLET)@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})@ConditionalOnMissingBean({ WebMvcConfigurationSupport.class})@AutoConfigureOrder(-2147483638)@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})public class WebMvcAutoConfiguration { public static final String DEFAULT_PREFIX = ""; public static final String DEFAULT_SUFFIX = ""; private static final String[] SERVLET_LOCATIONS = new String[]{ "/"}; public WebMvcAutoConfiguration() { } @Bean @ConditionalOnMissingBean({ HiddenHttpMethodFilter.class}) @ConditionalOnProperty( prefix = "spring.mvc.hiddenmethod.filter", name = { "enabled"}, matchIfMissing = false )
SpringBoot所有的自动配置 都是在启动的时候扫描并加载,META-INF/spring.factories中所有的内容, 但并不是所有的自动配置类都生效, 其内部会有一个判断条件, 判断条件是 是否导入了这个配置对应的start启动器, 如果导入了有了启动器才会进行自动配置
在SpringBoot中启动tomcat的工作在刷新上下这一步。而tomcat的启动主要是实例化两个组件:Connector、Container,一个tomcat实例就是一个Server,一个Server包含多个Service,也就是多个应用程序,每个Service包含多个Connector和一个Container,而一个Container下又包含多个子容器。
tomcat本身就是一个web容器, 他使用socket编程实现处理请求和返回响应的数据封装, 所以在springboot中就使用tomcat源码实现这个逻辑
而其中我们常用的有两个:TomcatServletWebServerFactory和JettyServletWebServerFactory。
开发阶段对我们来说使用内置的tomcat是非常够用了,当然也可以使用jetty。
getWebServer这个方法创建了Tomcat对象, 返回的就是一个TomcatWebServer。
tomcat结构图
tomcat最顶层容器是Server,代表着整个服务器,一个Server包含多个Service。从上图可以看除Service主要包括多个Connector和一个Container。Connector用来处理连接相关的事情,并提供Socket到Request和Response相关转化。Container用于封装和管理Servlet,以及处理具体的Request请求。
综上所述,一个tomcat只包含一个Server,一个Server可以包含多个Service,一个Service只有一个Container,但有多个Connector,这样一个服务可以处理多个连接。
多个Connector和一个Container就形成了一个Service,有了Service就可以对外提供服务了,但是Service要提供服务又必须提供一个宿主环境,那就非Server莫属了,所以整个tomcat的声明周期都由Server控制。
转载地址:http://znsci.baihongyu.com/