SpringBoot——入门及原理

SpringBoot用来简化Spring应用开发,约定大于配置,去繁从简,是由Pivotal团队提供的全新框架。其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置(有特殊需求可以添加自己的配置覆盖默认配置),从而使开发人员不再需要定义样板化的配置。SpringBoot可以看成是J2EE的一站式解决方案。

一、SpringBoot 的优点

【1】快速创建独立运行的Spring项目以及与主流框架集成。
【2】使用嵌入式的Servlet容器,应用无需打成war包,可以打成jar包,通过java -jar的方式直接运行。
【3】starters(启动器)自动依赖与版本控制。
【4】大量的自动配置,简化开发,也可以修改默认值。
【5】无需配置XML,无代码生成,开箱即用。
【6】准生产环境的运行时应用监控。
【7】与云计算的天然集成。

二、解决微服务部署和运维难的问题:Spring Boot

 如上的流程依次为: 搭建项目 构建连接 批处理

三、Spring Boot 入门项目

HelloWorld(也可以参考五,快速创建一个 SpringBoot项目)

【1】准备环境:Mavensettings.xml配置文件的profiles标签添加如下信息:

<profile>
<id>jdk-1.8</id>
<activation><activeByDefault>true</activeByDefault><jdk>1.8</jdk>
</activation>
<properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>

【2】将IDEAMaven更换为我们自己本地安装的Maven。(自行百度更换)创建一个maven工程[jar],在pom.xml中导入如下依赖:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version>
</parent>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

【3】编写一个主程序,启动SpringBoot应用

@SpringBootApplication
public class Hello {public static void main(String[] args) throws Exception {//启动spring应用SpringApplication.run(Hello.class, args);}
}

【4】编写相关的ControllerService

@Controller
public class HelloController {@ResponseBody@RequestMapping("/hello")public String hello(){return "hello world!";}
}

【5】运行主测试程序。简化部署应用<可以将应用打包成一个可执行的jar包>:通过Maven Projects中 的package(双击)即可。生成jar的位置:默认在项目的target目录下的“项目名称.jar”文件。运行jar:在命令行可以通过 “java -jar jar文件名.jar” 命令运行项目。

<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>

四、Hello World 探究(POM文件)

【1】父项目[spring-boot-starter-parent]:

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version>
</parent>

【2】进入spring-boot-starter-parent发现它还有一个父项目 :

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.0.0.RELEASE</version><relativePath>../../spring-boot-dependencies</relativePath>
</parent>

【3】进入spring-boot-dependencies后,发现如下信息,与之前我们创建的分布式项目继承的Maven父项目功能是一样的,用来管理所有jar包依赖的版本。称为SpringBoot的版本仲裁中心,以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖,需要声明版本号)

<properties><activemq.version>5.15.3</activemq.version><antlr2.version>2.7.7</antlr2.version><appengine-sdk.version>1.9.62</appengine-sdk.version><artemis.version>2.4.0</artemis.version><aspectj.version>1.8.13</aspectj.version><assertj.version>3.9.1</assertj.version><... 此处省略 .../>
</properties>

【4】启动器[spring-boot-starter-web]

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-webspring-boot-starterspring-boot场景启动器;进入官网可以到有许多场景启动器,简单点说就是通过此功能将相关jar包给组合在起来,我们使用时只需要引入一个Web Starter就可以轻松搞定。Spring Boot将所有的功能场景都抽取出来,做成一个个的 starters(启动器),只需要在项目里面引入这些starter相关场景,所有依赖都会导入进来。要用什么功能就导入什么场景启动器。

点击web右边的pom可以看到SpringBoot为我们依赖的其它jar包,帮我们导入了web模块正常运行所依赖的所有组件。如下:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency>
</dependencies>

【5】主程序类(Java类):@SpringBootApplication:此注解声明的类,是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot

//@ImportResource(locations={"classpath:bean.xml"})
//@SpringBootApplication 来标注一个主程序类,说明这是一个SpringBoot应用
@SpringBootApplication
public class HellowordQuickStartApplication {public static void main(String[] args) {/*SpringBoot应用启动项HellowordQuickStartApplication.class 参数必须是用@SpringBootApplication注解修饰的类*/SpringApplication.run(HellowordQuickStartApplication.class, args);}
}

@SpringBootApplication(主要由:@SpringBootConfiguration/@EnableAutoConfiguration/@ComponentScan组成)

@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) })
public @interface SpringBootApplication {

@SpringBootConfiguration:标注在某个类上,表示此类是一个SpringBoot的配置类。由以下注解组合形成:配置类 == 配置文件,配置类也是容器的一个组件,底层由@Component等等组成。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration //表示此类是一个配置类  是spring的一个组件
public @interface SpringBootConfiguration {

@EnableAutoConfiguration:开启自动配置功能。也是一个组合注解,由以下注解组成(部分重要注解):

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

@AutoConfigurationPackage:自动依赖相关的配置包,也是一个组合注解,主要由@import等注解组合

@Import({Registrar.class})//给容器中导入一个组件;导入的组件由此组建决定。
public @interface AutoConfigurationPackage {

进入@Import(Registrar.class)中的Registrar类中,通过断点,可以查看到我注释的一些信息。

static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {Registrar() {}//registerBeanDefinitions方法中的metadata可以查看到我们启动类使用的注解 @SpringBootApplicationpublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {AutoConfigurationPackages.register(registry, new String[]{(new AutoConfigurationPackages.PackageImport(metadata)).getPackageName()});}//new AutoConfigurationPackages.PackageImport(metadata) 可以解析出我们当前主启动所在的package包public Set<Object> determineImports(AnnotationMetadata metadata) {return Collections.singleton(new AutoConfigurationPackages.PackageImport(metadata));}
}

@Import(Registrar.class)作用:将主配置类的所在包以及下边所有子包里面的所有组件扫描到Spring容器中。这也就能理解为什么会自动扫描我们写的@Controller类了。

@Import(AutoConfigurationImportSelector.class):进入AutoConfigurationImportSelector.class类中,查看如下方法:

public String[] selectImports(AnnotationMetadata annotationMetadata) {if(!this.isEnabled(annotationMetadata)) {return NO_IMPORTS;} else {try {AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);AnnotationAttributes attributes = this.getAttributes(annotationMetadata);// 主要用到的是 这个 configurations 后面会有重点说明List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);configurations = this.removeDuplicates(configurations);configurations = this.sort(configurations, autoConfigurationMetadata);Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);this.checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = this.filter(configurations, autoConfigurationMetadata);this.fireAutoConfigurationImportEvents(configurations, exclusions);return StringUtils.toStringArray(configurations);} catch (IOException var6) {throw new IllegalStateException(var6);}}
}

这是导入组件的选择器方法,将所有需要导入的组件以全类名的方式返回,这些组件最终被添加到容器中。其中List<String> configurations会给容器中导入非常多的自动配置类[xxxAutoConfiguration],就是给容器中导入这个场景需要的所有组件,并配置好这些组件。有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;自动配置类共109个,如下部分所示:

☹ 那么我们就有疑问,这些自动配置类都是从哪里来的?
进入这个方法:this.getCandidateConfigurations(annotationMetadata, attributes)

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// *** 后边需要了解的方法 ***//SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");return configurations;
}

进入SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader)方法,具体注释说明:

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {//org.springframework.context.ApplicationContextInitializerString factoryClassName = factoryClass.getName();return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);if(result != null) {return result;} else {try {//通过类加载器(classLoader获取)META-INF/spring.factories(也就是配置了109个自动配置类的文件) 资源Enumeration<URL> urls = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories");LinkedMultiValueMap result = new LinkedMultiValueMap();while(urls.hasMoreElements()) {URL url = (URL)urls.nextElement();UrlResource resource = new UrlResource(url);//将urls 当做一个properties配置文件Properties properties = PropertiesLoaderUtils.loadProperties(resource);Iterator var6 = properties.entrySet().iterator();while(var6.hasNext()) {Entry<?, ?> entry = (Entry)var6.next();//将META-INF/spring.factories文件中的EnableAutoConfiguration下的配置进行加载   如下图所示List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));result.addAll((String)entry.getKey(), factoryClassNames);}}cache.put(classLoader, result);return result;} catch (IOException var9) {throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);}}
}

我们进入其中一个自动配置类中看看SpringBoot是不是真的帮我们已经配置好了一些属性[WebMvcAutoConfiguration]:

//这里我就摘出一些重要的配置,来帮我我们观察即可。
@Configuration
public class WebMvcAutoConfiguration {@Bean@ConditionalOnMissingBean/** 视图解析器 , SpringBoot中的所有配置文件都是.java形式,方法的名字,就是以前xml中的id。等等都是用注解表示的,这个我们后面会重点说明,这里就先了解一下*///我们可以看到SpringBoot已经帮我们配置好了视图解析器 等等一些功能 我们直接使用就好public InternalResourceViewResolver defaultViewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix(this.mvcProperties.getView().getPrefix());resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;}
}

总结: SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作。如此一来,就具有我们在SSM等环境下写了一大堆配置文件后才具有的功能。而这些所有配置文件都在spring-boot-autoconfigure-2.0.0.RELEASE.jar 中。

五、使用 Spring Initializer 快速创建 Spring Boot 项目

注意:Artifact中不能大小写混合使用。

通过需求选择starts,例如选择Web

我们就会发现pom.xml文件中,就会自动配置了我们引入的starts

<!-- 摘取一部分 -->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.RELEASE</version><relativePath/> <!-- lookup parent from repository -->
</parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version>
</properties>
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
</dependencies>

添加controller层: 新注解@RestController == @ResponseBody@Controller的合体;

//这个类的所有方法返回的数据直接写给浏览器(如果是对象转为JSON)
//@ResponseBody@Controller
@RestController
public class HelloWordController {@RequestMapping("/hello")public String hello(){return "hell";}
}

优点: 默认生成的SpringBoot项目,我们只需要编写自己的逻辑。默认生成的Resources配置文件的目录结构:
【1】static:保存所有的静态资源。 [js/css/image]
【2】templates:保存所有的模板页面[SpringBoot默认jar包使用嵌入式的 Tomcat,默认不支持JSP页面]但可以使用模板引擎。(freemarkerthymeleaf
【3】application.propertiesSpringBoot应用的配置文件。默认的配置都在此文件可以修改。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/149506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux上交叉编译qt库

linux上交叉编译qt库 Qt程序从X86平台Linux移植到ARM平台Linux需要做什么 1.在ubuntu上使用qt的源码交叉编译出Qt库 2.将编译好的库拷贝到开发板上并设置相应的环境变量&#xff08;库路径啥的&#xff09; 前两步一劳永逸&#xff0c;做一次就行 3.X86上写好程序代码&…

浅谈多回路电表在荷兰光伏系统配电项目中的应用

1.背景信息 Background&#xff1a; 随着全球化石能源&#xff08;石油&#xff0c;煤炭&#xff09;越来越接近枯竭&#xff0c;污染日趋严重&#xff0c;气候日益变暖等问题&#xff0c;全球多个国家和地区相继出台了法规政策&#xff0c;推动了光伏产业的发展。但是现有的光…

UE5 - ArchvizExplorer - 数字孪生城市模板 - 功能修改

数字孪生项目&#xff0c;大多是双屏互动&#xff0c;而非下方菜单点击&#xff0c;所以要做一番改造 参考&#xff1a;https://blog.csdn.net/qq_17523181/article/details/133853099 1. 去掉提示框 打开BP_MasterMenu_Widget&#xff0c;进入EventGraph&#xff0c;断开Open…

给折腿的罗技G512键盘换键帽

文章目录 1\. 引言2\. 操作2.1. 用打火机烤2.2. 用钳子拔出来2.2.1. 拔出成功2.2.2. 放大细看2.3. 更换键帽 1. 引言 G512的轴采用的是塑料连接&#xff0c;特别容易腿折在里面&#xff0c;换着的时候&#xff0c;得先把这个卡在里面的塑料腿拿出来才行 放大效果图 2. 操作 可…

Spring Boot中使用Redis进行大数据缓存

Spring Boot中使用Redis进行大数据缓存 在Spring Boot中使用Redis进行大数据缓存是一种常见的做法&#xff0c;因为Redis是一种高性能的内存数据库&#xff0c;适用于缓存大量数据。以下是说明和示例代码&#xff0c;演示如何在Spring Boot项目中使用Redis进行大数据缓存。 步…

龙讯旷腾PWmat发PRL:多k点计算的NAMD方法应用于小型超胞与在等效的大型超胞中进行的单个Γ点模拟之间的一致性

文章信息 作者信息&#xff1a;郑帆&#xff0c;汪林望 通信单位&#xff1a;上海科技大学 中国科学院半导体所 背景导读 固态材料中的超快载流子动力学在能源材料、光电子学、传感器和量子材料等领域起着关键作用。随着超快实验技术在固态系统中载流子动力学研究中的快速发…

纯CSS动态渐变文本特效

如图所示&#xff0c;这是一个炫酷的文本渐变效果&#xff0c;如同冰岛的极光一般。本次的文章让我们逐步分解代码&#xff0c;了解其实现原理。 基于以上动图效果可以分析以下是本次动效实现的主要几点&#xff1a; 文本中有多个颜色的动画每个颜色显示的半径不同&#xff0…

MCU内存基础知识

文章目录 一、存储器分类二、C语言内存分区内存区三、STM32启动文件分析四、应用分析 一、存储器分类 RAM&#xff08;Random Access Memory) &#xff1a;掉电之后就丢失数据&#xff0c;读写速度块 ROM (Read Only Memory) &#xff1a;掉电之后仍然可以保持数据 单片机的RA…

Springboot 项目启动类放置位置

文章目录 Springboot 项目启动类放置位置springboot 默认包扫描机制启动类放在特定位置springboot 启动注解理解配置启动类扫描特定的包1、 ComponentScan2、利用 SpringBootApplication 注解的 scanBasePackages 属性 Springboot 项目启动类放置位置 如果我们使用 IDEA 或者 …

将Agent技术的灵活性引入RPA,清华等发布自动化智能体ProAgent

近日&#xff0c;来自清华大学的研究人员联合面壁智能、中国人民大学、MIT、CMU 等机构共同发布了新一代流程自动化范式 “智能体流程自动化” Agentic Process Automation&#xff08;APA&#xff09;&#xff0c;结合大模型智能体帮助人类进行工作流构建&#xff0c;并让智能…

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件

Openlayer【二】—— 绘制不同的点、线以及给其添加监听事件 接上篇&#xff1a;OpenLayer初始化 在openlayer当中&#xff0c;图层Layer与地图源Source是一对一的关系。当创建了一个图层Layer&#xff0c;相应的需要给图层添加地图源Source&#xff0c;然后将图层Layer添加到…

浅谈无线测温产品在菲律宾某工厂配电项目的应用

摘要&#xff1a;配电系统是由多种配电设备和配电设施所组成的变换电压和直接向终端用户分配电能的一个电力网络系统。由于配电系统作为电力系统的一个环节直接面向终端用户&#xff0c;它的完善与否直接关系着广大用户的用电可靠性和用电质量&#xff0c;因而在电力系统中具有…

第14届蓝桥杯青少组python试题解析:23年5月省赛

选择题 T1. 执行以下代码&#xff0c;输出结果是&#xff08;&#xff09;。 lst "abc" print(lstlst)abcabc abc lstlst abcabc T2. 执行以下代码&#xff0c;输出的结果是&#xff08;&#xff09;。 age {16,18,17} print(type(sorted(age)))<class set&…

C++基础从0到1入门编程(三)

系统学习C 方便自己日后复习&#xff0c;错误的地方希望积极指正 往期文章&#xff1a; C基础从0到1入门编程&#xff08;一&#xff09; C基础从0到1入门编程&#xff08;二&#xff09; 参考视频&#xff1a; 1.黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难 2.系统…

企业计算机服务器中了faust勒索病毒怎么办,faust勒索病毒解密文件恢复

网络技术的不断应用发展&#xff0c;为企业注入了新的生产运营方式&#xff0c;计算机服务器为企业的数据存储提供了便利&#xff0c;让企业的生产运营得到了有力保障&#xff0c;近期&#xff0c;云天数据恢复中心陆续接到很多企业的求助&#xff0c;企业的计算机服务器遭到了…

基于单片机设计的电子指南针(LSM303DLH模块(三轴磁场 + 三轴加速度)

一、前言 本项目是基于单片机设计的电子指南针&#xff0c;主要利用STC89C52作为主控芯片和LSM303DLH模块作为指南针模块。通过LCD1602液晶显示屏来展示检测到的指南针信息。 在日常生活中&#xff0c;指南针是一种非常实用的工具&#xff0c;可以帮助我们确定方向&#xff0…

人工智能-循环神经网络通过时间反向传播

到目前为止&#xff0c;我们已经反复提到像梯度爆炸或梯度消失&#xff0c; 以及需要对循环神经网络分离梯度。 例如&#xff0c;我们在序列上调用了detach函数。 为了能够快速构建模型并了解其工作原理&#xff0c; 上面所说的这些概念都没有得到充分的解释。 本节将更深入地探…

MTK Pump Express 快速充电原理分析

1 MTK PE 1.1 原理 在讲正文之前&#xff0c;我们先看一个例子。 对于一块电池&#xff0c;我们假设它的容量是6000mAh&#xff0c;并且标称电压是3.7V&#xff0c;换算成Wh(瓦时)为单位的值是22.3Wh(6000mAh*3.7V)&#xff1b;普通的充电器输出电压电流是5V2A(10W)&#xff0c…

纯CSS实现炫酷文本阴影效果

如图所示&#xff0c;这是一个文本阴影效果&#xff0c;阴影有多个颜色&#xff0c;鼠标悬停时文本阴影效果消失&#xff0c;文本回到正常的效果。让我们逐步分解代码&#xff0c;看看如何使用纯CSS实现这个效果的。 基于以上动图可以分析出以下是本次实现的主要几个功能点&am…

【软件工程师从0到1】- Java面向对象基础 (知识汇总)

前言 介绍&#xff1a;大家好啊&#xff0c;我是hitzaki辰。 社区&#xff1a;&#xff08;完全免费、欢迎加入&#xff09;日常打卡、学习交流、资源共享的知识星球。 自媒体&#xff1a;我会在b站/抖音更新视频讲解 或 一些纯技术外的分享&#xff0c;账号同名&#xff1a;hi…