五莲县财源建设网站,免费制作论坛网站模板,深圳深圳做网站,网站开发结构文档源码剖析 - 依赖管理问题 1#xff1a;为什么导入 dependency 时不需要指定版本#xff1f;在 Spring Boot 项目中#xff0c;pom.xml 核心依赖为 spring-boot-starter-parent 和 spring-boot-starter-web#xff0c;其中 spring-boot-starter-parent 是版本管理的核心为什么导入 dependency 时不需要指定版本在 Spring Boot 项目中pom.xml核心依赖为spring-boot-starter-parent和spring-boot-starter-web其中spring-boot-starter-parent是版本管理的核心1. spring-boot-starter-parent 核心作用!-- Spring Boot父项目依赖管理 -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.2.9.RELEASE/version relativePath/ !-- lookup parent from repository -- /parentspring-boot-starter-parent底层做了三件核心事properties 节点定义 Java 版本1.8、编码UTF-8、Maven 编译版本等基础配置build 节点配置资源过滤支持多环境配置文件如application-dev.yml、插件版本管理继承 spring-boot-dependencies这是真正的版本管理核心通过dependencyManagement锁定所有 Spring Boot 组件版本。2. spring-boot-dependencies 核心配置!-- 版本属性定义 -- properties activemq.version5.15.13/activemq.version antlr2.version2.7.7/antlr2.version !-- 所有组件版本定义 -- /properties !-- 依赖版本管理 -- dependencyManagement dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot/artifactId version${revision}/version /dependency !-- 所有核心组件版本锁定 -- /dependencies /dependencyManagement结论项目继承spring-boot-starter-parent后自动继承了spring-boot-dependencies的版本锁定因此无需手动指定依赖版本。问题 2项目运行依赖的 JAR 包从何而来spring-boot-starter-web是场景化依赖启动器核心作用是依赖传递dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependencyspring-boot-starter-web内部封装了 Web 开发所需的所有底层依赖spring-boot-starter-tomcat内置 Tomcat 服务器spring-boot-starter-validation参数校验spring-webspring-webmvcSpring MVC 核心结论场景启动器通过依赖传递引入所有相关 JAR 包版本由spring-boot-starter-parent统一管理。第三方启动器如druid-spring-boot-starter需手动指定版本。源码剖析 - 自动配置核心问题Spring Boot 如何实现自动配置Spring Boot 自动配置核心是SpringBootApplication注解其本质是组合注解Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented Inherited SpringBootConfiguration // 标识配置类 EnableAutoConfiguration // 核心开启自动配置 ComponentScan(...) // 组件扫描 public interface SpringBootApplication { Class?[] exclude() default {}; // 排除自动配置类 String[] excludeName() default {}; // 排除自动配置类名 String[] scanBasePackages() default {}; // 自定义扫描包 }1. SpringBootConfiguration本质是Configuration标识当前类为 Spring 配置类等价于 XML 配置文件。2. EnableAutoConfiguration核心AutoConfigurationPackage // 自动配置包 Import(AutoConfigurationImportSelector.class) // 导入自动配置选择器 public interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY spring.boot.enableautoconfiguration; Class?[] exclude() default {}; String[] excludeName() default {}; }1AutoConfigurationPackage通过Import(AutoConfigurationPackages.Registrar.class)注册当前主类所在包为自动配置基础包用于扫描用户自定义组件。2AutoConfigurationImportSelector 核心逻辑自动配置的核心流程加载候选配置类从META-INF/spring.factories读取EnableAutoConfiguration对应的自动配置类排除指定类排除exclude属性指定的配置类条件过滤通过ConditionalOnClass/ConditionalOnBean等注解过滤不符合条件的配置类注册有效配置类将最终符合条件的配置类注入 IOC 容器。3. 条件注解Conditional 系列注解作用ConditionalOnBean容器存在指定 Bean 时生效ConditionalOnClass类路径存在指定类时生效ConditionalOnMissingBean容器不存在指定 Bean 时生效ConditionalOnWebApplicationWeb 环境下生效ConditionalOnProperty配置文件存在指定属性时生效4. 自动配置示例HttpEncodingAutoConfigurationConfiguration EnableConfigurationProperties(HttpEncodingProperties.class) ConditionalOnWebApplication // Web 环境生效 ConditionalOnClass(CharacterEncodingFilter.class) // 存在字符编码过滤器 ConditionalOnProperty(prefix spring.http.encoding, value enabled, matchIfMissing true) public class HttpEncodingAutoConfiguration { private final HttpEncodingProperties properties; Bean ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { // 构建过滤器并绑定配置属性 } }自动配置核心总结加载spring.factories中的自动配置类排除指定的配置类条件过滤Conditional 系列注册有效配置类到 IOC 容器通过xxxProperties绑定配置文件属性。源码剖析 - Run 方法执行流程Spring Boot 启动入口SpringBootApplication public class MyTestMVCApplication { public static void main(String[] args) { SpringApplication.run(MyTestMVCApplication.class, args); } }1. SpringApplication 初始化public SpringApplication(ResourceLoader resourceLoader, Class?... primarySources) { this.resourceLoader resourceLoader; this.primarySources new LinkedHashSet(Arrays.asList(primarySources)); this.webApplicationType WebApplicationType.deduceFromClasspath(); // 推断应用类型 setInitializers(getSpringFactoriesInstances(ApplicationContextInitializer.class)); // 初始化器 setListeners(getSpringFactoriesInstances(ApplicationListener.class)); // 监听器 this.mainApplicationClass deduceMainApplicationClass(); // 推断主类 }2. run () 方法核心流程public ConfigurableApplicationContext run(String... args) { StopWatch stopWatch new StopWatch(); stopWatch.start(); ConfigurableApplicationContext context null; CollectionSpringBootExceptionReporter exceptionReporters new ArrayList(); // 1. 初始化监听器 SpringApplicationRunListeners listeners getRunListeners(args); listeners.starting(); try { // 2. 构建环境系统变量、配置文件等 ApplicationArguments applicationArguments new DefaultApplicationArguments(args); ConfigurableEnvironment environment prepareEnvironment(listeners, applicationArguments); // 3. 创建应用上下文 context createApplicationContext(); // 4. 上下文前置处理 prepareContext(context, environment, listeners, applicationArguments, printedBanner); // 5. 刷新上下文IOC 容器初始化核心 refreshContext(context); // 6. 上下文后置处理 afterRefresh(context, applicationArguments); stopWatch.stop(); listeners.started(context); callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } listeners.running(context); return context; }3. 核心步骤详解步骤核心操作初始化监听器加载spring.factories中的SpringApplicationRunListener构建环境加载系统环境、配置文件application.yml/properties创建上下文根据应用类型SERVLET/REACTIVE/NONE创建对应上下文上下文前置处理注册主类 BeanDefinition、加载初始化器刷新上下文IOC 容器初始化BeanDefinition 扫描、加载、注册上下文后置处理执行自定义扩展逻辑源码剖析 - 自定义 Starter1. Starter 机制核心Starter 是 Spring Boot 「约定大于配置」的体现通过封装通用功能实现「引入即生效」。2. 自定义 Starter 规范命名官方 Starter 为spring-boot-starter-xxx自定义建议xxx-spring-boot-starter核心自动配置类 spring.factories配置。3. 自定义 Starter 实战1创建 Starter 工程Maven JAR依赖dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-autoconfigure/artifactId version2.2.9.RELEASE/version /dependency /dependencies2编写配置属性类ConfigurationProperties(prefix simplebean) public class SimpleBean { private int id; private String name; // getter/setter/toString }3编写自动配置类Configuration ConditionalOnBean(ConfigMarker.class) // 热插拔条件 EnableConfigurationProperties(SimpleBean.class) public class MyAutoConfiguration { static { System.out.println(MyAutoConfiguration init....); } Bean public SimpleBean simpleBean() { return new SimpleBean(); } }4配置 spring.factories在resources/META-INF/spring.factories中添加org.springframework.boot.autoconfigure.EnableAutoConfiguration\ com.lagou.config.MyAutoConfiguration5热插拔实现标记类public class ConfigMarker {}启用注解Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Import(ConfigMarker.class) public interface EnableRegisterServer {}4. 使用自定义 Starter1引入依赖dependency groupIdcom.lagou/groupId artifactIdzdy-spring-boot-starter/artifactId version1.0-SNAPSHOT/version /dependency2配置属性simplebean.id1 simplebean.name自定义starter3测试Autowired private SimpleBean simpleBean; Test public void zdyStarterTest() { System.out.println(simpleBean); }源码剖析 - 内嵌 Tomcat1. 默认容器与切换Spring Boot 引入spring-boot-starter-web后默认使用 Tomcat切换容器只需排除 Tomcat 依赖并引入其他容器dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId exclusions exclusion artifactIdspring-boot-starter-tomcat/artifactId groupIdorg.springframework.boot/groupId /exclusion /exclusions /dependency !-- 引入 Jetty -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-jetty/artifactId /dependency2. 内嵌 Tomcat 自动配置原理1自动配置类ServletWebServerFactoryAutoConfiguration从spring.factories加载通过Import导入 Tomcat/Jetty/Undertow 自动配置类Configuration AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) ConditionalOnClass(ServletRequest.class) ConditionalOnWebApplication(type Type.SERVLET) Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration {}2Tomcat 启动核心TomcatServletWebServerFactory的getWebServer()方法创建并启动 Tomcatpublic WebServer getWebServer(ServletContextInitializer... initializers) { Tomcat tomcat new Tomcat(); // 配置 Tomcat 端口、连接器等 tomcat.start(); // 启动 Tomcat return new TomcatWebServer(tomcat); }3Tomcat 启动触发点在refreshContext()中调用onRefresh()-createWebServer()最终触发getWebServer()启动 Tomcat。源码剖析 - 自动配置 SpringMVC1. 核心自动配置类DispatcherServletAutoConfigurationAutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) Configuration ConditionalOnWebApplication(type Type.SERVLET) ConditionalOnClass(DispatcherServlet.class) AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class) public class DispatcherServletAutoConfiguration {}2. 自动配置核心逻辑1配置 DispatcherServletBean(name DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServlet dispatcherServlet(HttpProperties httpProperties, WebMvcProperties webMvcProperties) { DispatcherServlet dispatcherServlet new DispatcherServlet(); // 配置 DispatcherServlet 属性 return dispatcherServlet; }2注册 DispatcherServlet 到 ServletContext通过DispatcherServletRegistrationBean实现 Servlet 注册Servlet 3.0 规范Bean(name DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) ConditionalOnBean(value DispatcherServlet.class, name DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties) { DispatcherServletRegistrationBean registration new DispatcherServletRegistrationBean(dispatcherServlet, webMvcProperties.getServlet().getPath()); // 配置加载顺序、名称等 return registration; }3. Servlet 注册核心流程DispatcherServletRegistrationBean继承ServletRegistrationBean通过onStartup()调用servletContext.addServlet()注册 DispatcherServlet最终在 Spring Boot 启动时完成 Spring MVC 核心组件的自动注册。核心总结Spring Boot 自动配置 Spring MVC 的本质是通过DispatcherServletAutoConfiguration配置 DispatcherServlet通过 Servlet 3.0 规范的servletContext.addServlet()动态注册 DispatcherServlet支持通过application.yml配置 Spring MVC 核心属性如路径、加载顺序。关键补充Servlet 3.0 规范支持动态注册三大组件servletContext.addServlet()注册 ServletservletContext.addFilter()注册 FilterservletContext.addListener()注册 Listener这是 Spring Boot 无需 web.xml 即可配置 Web 组件的核心原理。