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】准备环境: 为Maven的settings.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】将IDEA的 Maven更换为我们自己本地安装的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】编写相关的Controller、Service类
@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-web:spring-boot-starter指spring-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页面]但可以使用模板引擎。(freemarker、thymeleaf)
【3】application.properties:SpringBoot应用的配置文件。默认的配置都在此文件可以修改。
相关文章:
SpringBoot——入门及原理
SpringBoot用来简化Spring应用开发,约定大于配置,去繁从简,是由Pivotal团队提供的全新框架。其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置(有特殊需求可以添加自己的配置覆盖默认配…...
js实现页面滚动时自动切换Sidebar标签,点击标签自动滚动页面
js实现页面滚动时自动切换Sidebar侧边导航标签,点击标签自动滚动页面 <van-sidebar class"sidebar" v-model"activeKey"><van-sidebar-item :title"i.title" click"onChange(i)" v-for"(i,k) in activeList&…...
Failed to load resource: net::ERR_UPLOAD_FILE_CHANGED 谷歌浏览器就会有这个问题 其他的浏览器没有
Failed to load resource: net::ERR_UPLOAD_FILE_CHANGED 10 10: Difficulties in file uploading through all browsers and applications...
微信小程序 prettier 格式化
一、安装prettier插件 二、打开设置 然后再打开setting.json 新增代码 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","prettier.documentSelectors": ["**/*.wxml", "**/*.wx…...
SystemVerilog学习 (10)——线程控制
一、概述 在实际硬件中,时序逻辑通过时钟沿来激活,组合逻辑的输出则随着输人的变化而变化。所有这些并发的活动在Verilog 的寄存器传输级上是通过initial和 always块语句、实例化和连续赋值语句来模拟的。为了模拟和检验这些语句块,测试平台使用许多并发执行的线程。在测试平台…...
【开题报告】基于SpringBoot的二手汽车交易平台的设计与实现
1.研究背景 随着社会经济的不断发展,二手汽车交易市场逐渐壮大,二手汽车交易平台作为一种重要的电子商务形式备受关注。本文基于Spring Boot框架,旨在设计与实现一个高效、安全、用户友好的二手汽车交易平台。本文将深入探讨二手汽车市场发展…...
Python 爬虫入门
文章目录 Python 爬虫入门requests 库beautifulsoup4库函数findall(),find()函数get() 爬虫实例 1:抓小说爬虫实例 2:抓豆瓣 top 250 的电影信息后记 Python 爬虫入门 Python 的爬虫功能使得程序员可以快速抓取并分析网页中的信息࿰…...
[ 加密 ] SHA256
SHA256 例程 一般文件的完整性要使用md5或者sha进行完整性校验,这里提供两个函数, intact_update_sha 是计算指定文件SHA值并保存到SHA文件 intact_check_sha 计算文件SHA值并和SHA文件进行对比 编译方法: gcc demo.c -lssl -lcrypto #…...
推荐一个windows上传linux服务器/linux服务器的docker镜像的工具,摆脱docker cp,以及解决常见问题。
Lrzsz,又称为lrz和lsz,是一个用于在Unix、Linux、macOS等操作系统上进行串行文件传输的工具。它支持基于X/Y/ZModem协议的文件传输,能够通过串口或者Telnet/SSH等网络连接进行文件传输。Lrzsz具有传输速度快、可靠性高、易于使用等特点&#…...
《QT从基础到进阶·三十五》QT插件实现侧边工具栏tabBar
tabBar是用QT插件实现的一个dll,对于插件的使用可以参考文章: 《QT从基础到进阶三十三》QT插件开发QtPlugin 源码放在文章末尾 该功能类似侧边工具栏,可以在该标签栏上添加自己开发的界面,实现代码如下: 1、所有功能…...
风丘电动汽车热管理方案 为您的汽车研发保驾护航
热管理技术作为汽车节能、提高经济性和保障安全性的重要措施,在汽车研发过程中具有重要作用。传统燃油汽车的热管理系统主要包括发动机、变速器散热系统和汽车空调,而电动汽车的热管理系统在燃油汽车热管理架构的基础之上,又增加了电机电控热…...
每日一练 | 华为认证真题练习Day134
1、开启标准STP协议的交换机可能存在哪些端口状态?(多选) A. Discarding B. Listening C. Disabled D. Forwarding 2、下列路由协议中优先级最高的是? A. Direct B. RIP C. OSPF D. Static 3、参考如图所示的输出结果&…...
python连接hive报错:TypeError: can‘t concat str to bytes
目录 一、完整报错 二、解决 三、 其他报错 四、impala方式连接hive 或者直接使用 pip install pyhive[hive] 安装。需要先 pip uninstall pyhive。 一、完整报错 Traceback (most recent call last): File "D:/Gitlab/my_world/hive2csv.py", line 18, in <…...
虹科示波器 | 汽车免拆检修 | 2015款奔驰G63AMG车发动机偶尔自动熄火
一、故障现象 一辆2015款奔驰G63AMG车,搭载157发动机,累计行驶里程约为9.4万km。车主反映,该车低速行驶时,发动机偶尔会自动熄火,故障大概1个星期出现1次。 二、故障诊断 接车后路试,故障未能再现。用故障检…...
10 Redis的持久化
Redis支持RDB和AOF两种持久化机制 1、RDB(Redis DataBase) 是对命令的全量快照随着key的数量增大,那么写入磁盘的开销也会越来越大 2、RDB文件的生成是否会阻塞主线程 save: 使用save的方式会阻塞主线程,影响redis的性能 bgsave: 一般情况下不会阻塞…...
【Linux入侵日志排查】
在Linux系统中,不同的服务和应用程序可能会产生不同格式的日志记录。以下是一些常见类型的日志文件及其格式说明: 以下是一些常见的 Linux 日志字段格式说明,以及具体的示例: /var/log/auth.log:此日志文件包含与身份…...
从哪些方面分析Linux内核源码
从这些方面分析Linux内核源码,这里提供一个大致的大纲: 一、Linux内核源码概述 1. 什么是Linux内核? 2. Linux内核的主要功能 3. Linux内核的版本控制 4. Linux内核的组织结构 二、Linux内核编译与配置 1. 获取Linux内核源码 2. 安装…...
C#WPF数据模板应用实例
一、数据模板定义 数据模板是一块定义如何显示绑定的数据对象的XAML标记。 有两种类型的控件支持数据模板: 1、内容控件 通过ContentTemplate属性支持数据模板。内容模板用于显示任何放置在Content属性中的内容。 2、列表控件(继承自ItemsControl类的控件) 通过ItemsTem…...
ansible练习题1
安装并配置ansible 在控制节点上安装并配置Ansible,要求如下: | 安装所需的软件包: 创建静态inventory文件/home/student/ansible/inventory ,要求如下: servera属于dev主机组 serverb属于test和balancers主机组 serverc和serverd属于prod主机组 …...
六大排序详讲(直接插入排序+希尔排序+选择排序+堆排序+冒泡排序+快速排序)
文章目录 排序一、 排序的概念1.排序:2.稳定性:3.内部排序:4.外部排序: 二、插入排序1.直接插入排序2.希尔排序 三、选择排序1.直接选择排序方法一方法二直接插入排序和直接排序的区别 2.堆排序 四、交换排序1.冒泡排序2.快速排序…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度
文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
