(2)SpringBoot自动装配原理简介

SpringBoot自动装配

image-20250129011450796

这里写目录标题

  • SpringBoot自动装配
    • 启动器
    • 主程序
      • 自定义扫描包
      • @SpringBootApplication
        • @SpringBootConfiguration
        • @EnableAutoConfiguration
          • @AutoConfigurationPackage
          • @Import({AutoConfigurationImportSelector.class})选择器
            • AutoConfigurationEntry
            • getCandidateConfigurations
    • 组件添加
      • 代理设置
      • @import注解
      • Conditional注解
      • @ImportResource注解
    • 配置绑定
      • @ConfigurationProperties注解
      • @EnableConfigurationProperties注解
    • 主函数
      • @EnableAutoConfiguration注解
        • @AutoConfigurationPackage注解
        • @Import({AutoConfigurationImportSelector.class})
      • 按需开启
    • 自动装配流程
      • 条件装配流程
      • 修改默认配置

我们通过观察创建的SpringBoot项目的pom.xml文件发现他的核心依赖大部分在他的父工程中,长按ctrl并点击父项目就可以进入到父项目的文件,从浏览器上面下载压缩包的那种创建springBoot方式不能查看夫项目的文件。

spring-boot-dependencies是parent的父项目。

image-20250126232001767

在这里制定了大量的依赖版本,还有过滤器。

我们的pom.xml文件与之前不同的就是我们在引入依赖的时候可以不指定依赖的版本,这就是因为在父工程中指定了依赖的版本,我们没必要再写。当然,如果要引入他没有规定的依赖还是要声明版本的。

如果我们对他的依赖版本不满意,想要使用我们自己的,我们可以指定需要的版本

image-20250127092614695

这个就是修改mysql版本的方法。

启动器

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

项目自带的启动器,下面有很多的在他的基础上添加后缀的依赖,比如说-web配置内置的tomcat容器等

访问下面这个网址可以找到对于启动器的介绍

Build Systems :: Spring Boot

image-20250127093321786

image-20250126233141282

这里可以查询到我常用的依赖。如aop,缓存等的,我们也可以使用idea的分析依赖树功能,更好的查看我们项目中的依赖。

image-20250127093608520

主程序

首先alt+回车查看他的返回类型ConfigurableApplicationContext是一个IOC容器,我们通过getBeanDefinitionNames来打印一下它里面的所有组件。

package com.kang.start;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class StartApplication {public static void main(String[] args) {//ConfigurableApplicationContext是一个IOC容器ConfigurableApplicationContext run = SpringApplication.run(StartApplication.class, args);String[] names = run.getBeanDefinitionNames();for (String name:names) {System.out.println(name);}}
}

image-20250127095933200

说明他配置了dispathcer,我们之前学习的基本上所有的组件都可以在这里找到。

自定义扫描包

注意在官网上说的包结构的安排,只有把组件放在项目目录下才能扫描到。

image-20250127150206230

当然想要改变扫描的包也很简单,加一个这个

@SpringBootApplication(scanBasePackages = "com.kang")

image-20250127150607182

当然也有第二种方法就是直接把它里面的注解拽出来,这样配置就不会与SpringBootApplication标签里面的包扫描冲突

/*@SpringBootApplication*/@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.kang")
public class StartApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(StartApplication.class, args);String[] names = run.getBeanDefinitionNames();for (String name:names) {System.out.println(name);}}
}

这里我们也可以得出一个结论

@SpringBootApplication
等价于
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.kang")

在 [application.properties] 文件中我们发现,我们点开配置文件的源码以后,里面绑定的都是类,最后这些类都会注入到IOC容器中。

@SpringBootApplication

他的主程序很少,其中最关键的注解就是@SpringBootApplication声明它是springBoot程序,查看他的源文件会发现两个最重要的注解

@SpringBootConfiguration
@SpringBootConfiguration@Configuration@Component//这个注解代表他本质上还是一个spring的组件
@EnableAutoConfiguration
@EnableAutoConfiguration//自动导入配置文件;@AutoConfigurationPackage//自动配置包@Import({AutoConfigurationImportSelector.class})//导入选择器
@AutoConfigurationPackage
@Import({Registrar.class})

image-20250128235521109

通过Regist类我们可以发现的本质就是一个自动注册包的类

@Import({AutoConfigurationImportSelector.class})选择器

这两个配置注解在AutoConfigurationImportSelector这个类中有一个核心语句就是获取所有的配置

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
AutoConfigurationEntry

AutoConfigurationEntry获得自动配置的实体

image-20250129001747171

getCandidateConfigurations

了解一下getCandidateConfigurations的

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {ImportCandidates importCandidates = ImportCandidates.load(this.autoConfigurationAnnotation, this.getBeanClassLoader());List<String> configurations = importCandidates.getCandidates();Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring/" + this.autoConfigurationAnnotation.getName() + ".imports. If you are using a custom packaging, make sure that file is correct.");return configurations;
}

其中 "No auto configuration classes found in META-INF/spring/"这里说的就是自动配置的核心文件

image-20250127152152077

就是它,点开我们可以看到很多的配置,比如说常见的aop,jdbc等的配置。但是我们点开以后发现很多的都是爆红的,这说明我们并没有配置该组件,我们只要在pom文件中添加依赖,下载完成以后就不爆红了。

image-20250129011450796

组件添加

首先创建实体类

User类

package com.kang.start.pojo;public class User {String name;int age;@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}public User() {}public User(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}

Pet类

package com.kang.start.pojo;public class Pet {String name;public Pet() {}@Overridepublic String toString() {return "Pet{" +"name='" + name + '\'' +'}';}public String getName() {return name;}public void setName(String name) {this.name = name;}public Pet(String name) {this.name = name;}
}

然后注册到容器中的方法有两种

方法一:
配置beans.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user01" class="com.kang.start.pojo.User"><property name="age" value="18"/><property name="name" value="zhangsan"/></bean><bean id="Tomcat" class="com.kang.start.pojo.Pet"><property name="name" value="Tomcat"/></bean>
</beans>

方法二:

使用配置类(配置类本身也是组件)+注解

  1. @Configuration//声明配置类==xml文件
  2. @Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。
  3. @Bean(“Tom”)//自定义名称
package com.kang.start.config;import com.kang.start.pojo.Pet;
import com.kang.start.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration//声明配置类==xml文件
public class myConfig {@Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。public User user01(){return new User("xiaom",18);}@Bean("Tom")//自定义名称public Pet TomcatPet(){return new Pet("Tomcat");}
}

我们在主函数中输出一下

public class StartApplication {public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(StartApplication.class, args);String[] names = run.getBeanDefinitionNames();for (String name:names) {System.out.println(name);}}
}

image-20250127154604459

得到了我们注册的两个类

代理设置

@Configuration(proxyBeanMethods = true)

proxyBeanMethods参数是设置代理,当他默认值为true的时候,当我们创建两个对象的时候,他们的哈希地址是一样的,设置为false的时候就是不同的。

这就涉及到两种模式:

  1. Full:proxyBeanMethods = true,把创建的对象放在容器中,调用的时候从容器中取出来
  2. Lite:proxyBeanMethods = false,每次调用的时候创建对象。(轻量级模式)

举个例子:如果我们在User对象中绑定一个Pet类型的cat,当我们代理为true的时候,我们绑定的宠物就是容器中的cat,这就成功的让User绑定到了cat,但是如果代理设置为false,那么我们绑定的Pet就是新创建的,并不是我们在配置类中绑定的那个Pet。

总的来说,当我放入IOC的对象存在IOC依赖的时候就需要打开代理,当我们没有IOC依赖的时候就调成false,让我们更快的加载。因为他跳过了在IOC中检测的步骤。

@import注解

这个组件可以帮助我们在IOC容器中创建指定类型的组件

比如说,我们随便import一个组件,是自定义的

@Import({User.class})
@Configuration(proxyBeanMethods = true)
public class myConfig {@Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。public User user01(){return new User("xiaom",18);}@Bean("Tom")//自定义名称public Pet TomcatPet(){return new Pet("Tomcat");}
}

输出一下

public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(StartApplication.class, args);String[] names = run.getBeanNamesForType(User.class);for (String name:names) {System.out.println(name);}}

image-20250127171713282

他的名字就是类地址名。这就代表成功注册了

Conditional注解

他的作用是在指定条件下注册指定的类,看下他的源文件

image-20250127172306288

ctrl+H,我们发现他有很多很多的派生注解。

image-20250127173001574

首先解释一个方法containsBean,它可以检测容器中是否存在指定的类

我们先把tom组件注释掉

public static void main(String[] args) {ConfigurableApplicationContext run = SpringApplication.run(StartApplication.class, args);boolean tom = run.containsBean("tom");System.out.println("输出是否存在组件tom:"+tom);boolean user01 = run.containsBean("user01");System.out.println("输出是否存在组件user01:"+user01);}

image-20250127173638853

我们首先对User和Pet建立依赖

package com.kang.start.pojo;public class User {String name;int age;Pet pet;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public Pet getPet(Pet pet) {return this.pet;}public void setPet(Pet pet) {this.pet = pet;}public User(String name, int age) {this.name = name;this.age = age;}
}
@Configuration(proxyBeanMethods = true)
public class myConfig {@Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。public User user01(){User user = new User("xiaom", 18);user.setPet(TomcatPet());return user;}@Bean("Tom")//自定义名称public Pet TomcatPet(){return new Pet("Tomcat");}
}

使用一个注解@ConditionalOnBean(name = “Tom”)

@Configuration(proxyBeanMethods = true)
public class myConfig {@Bean("Tom")//自定义名称public Pet TomcatPet(){return new Pet("Tomcat");}@ConditionalOnBean(name = "Tom")//检测容器中是否存在Tom,如果存在则创建user01@Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。public User user01(){User user = new User("xiaom", 18);user.setPet(TomcatPet());return user;}
}

检测是否存在

image-20250127181448945

当我们注释掉Tom时

image-20250127181529172

user01也不会注册;也可以把它注解在整个类以外,如果存在这个类,下面所有的配置才会生效。

@ImportResource注解

它可以帮助我们自动导入beans.xml文件,比如说,在我们运行一个比较老的项目的时候他的配置用的全都是xml文件注册的bean,我们想要快速的把他的xml文件中的beans注册到我们的IOC容器中,我们就可以使用在各个注解。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="hehe" class="com.kang.start.pojo.Pet"><property name="name" value="Tomcat"/></bean><bean id="haha" class="com.kang.start.pojo.User"><property name="age" value="18"/><property name="name" value="zhangsan"/></bean>
</beans>

这样一个xml文件

@Configuration(proxyBeanMethods = true)
@ImportResource("classpath:beans.xml")//快速引入指定的bean注册文件
public class myConfig {@Bean("Tom")//自定义名称public Pet TomcatPet(){return new Pet("Tomcat");}@ConditionalOnBean(name = "Tom")@Bean//添加组件,方法名就是id,返回类型就是组件类型,返回值就是对象。public User user01(){User user = new User("xiaom", 18);user.setPet(TomcatPet());return user;}
}

image-20250127182738665

配置绑定

@ConfigurationProperties注解

简单来说就是使用Java读取到propertie文件中的内容,把它封装到JavaBean中,方便使用。

传统的方法就是使用Properties类读取配置文件的Key和value,遍历它们,然后一一对应的封装到JavaBean中。

这时可以使用一个注解@ConfigurationProperties(prefix = “(前缀)”)

prefix是前缀

具体的使用步骤:

首先新建Car类,为他加入get/set方法还有tostring方法,有参无参构造方法等

使用@Component注解来注册到IOC容器中

@ConfigurationProperties(prefix = “mycar”)//读取properties文件中前缀为mycar的方法

注意:properties文件中的前缀必须全小写,不能使用驼峰写法

package com.kang.start.pojo;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {public String brand;public Integer pirce;@Overridepublic String toString() {return "Car{" +"brand='" + brand + '\'' +", pirce=" + pirce +'}';}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public Integer getPirce() {return pirce;}public void setPirce(Integer pirce) {this.pirce = pirce;}public Car() {}public Car(String brand, Integer pirce) {this.brand = brand;this.pirce = pirce;}
}

properties文件:

mycar.brand=baoma
mycar.pirce=10000

在Controller类中用@Autowried注解来吧IOC容器中的car类拽下来

@RestController
public class myConfig {@AutowiredCar car;@RequestMapping("/car")public Car car(){return car;}
}

访问这个页面

image-20250128092016762

@EnableConfigurationProperties注解

当然,我们还要考虑一种情况,就是这个组件如果不是我们自定义的我们要把它注册到IOC容器中怎么办呐?我们也不能在人家的源文件中添加@Component注解

这个时候,我们可以在配置类当中使用这个注解

@EnableConfigurationProperties(类名.class)

代替@Component注解;

主函数

@EnableAutoConfiguration注解

查看他的源文件里面有两个核心的注解

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

他的源码:

@Import({Registrar.class})//给容器导入组件
public @interface AutoConfigurationPackage {

其中导入组件的时候用的是Registrar来导入一系列组件

image-20250128094347691

所以说@EnableAutoConfiguration注解的一个作用就是导入指定包下的所有组件

具体来说就是main程序所在包下的所有组件

@Import({AutoConfigurationImportSelector.class})

@EnableAutoConfiguration还有一个重要的注解

@Import({AutoConfigurationImportSelector.class})

这个注解,先查看AutoConfigurationImportSelector这个方法,他是一个批处理方法。

其中有一个selectImports。

image-20250128095154097

研究一下getAutoConfigurationEntry(annotationMetadata)这个方法

他就是给IOC容器中批量导入组件,我们来Debug一下

image-20250128095934198

getAutoConfigurationEntry(annotationMetadata)这个方法就是调用

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

这个方法,获取所有要导入容器中的类。

此外还有一个重要的工厂方法;

protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
}

利用工厂方法加载。

SpringFactoriesLoader方法

image-20250128213934438

默认他会扫描这个位置META-INF/spring.factories

在我们的自动装配核心类包spring-boot-autoconfigure-3.4.2.jar中

image-20250128214343134

说明这个文件里面声明了启动springBoot时要注册的所有配置类

按需开启

虽然所有的配置文件会全部配置,但是真正使用的时候只会按需配置。

比如说我们随便打开一个包

image-20250128223723179

条件配置,只有配置了指定的类才会继续下面的配置。最终会按照条件配置规则,按需装配

自动装配流程

条件装配流程

首先阅读一下aop类的源码

image-20250128224845584

image-20250128225040717

由于这个配置要求有Advice类,所以暂且将其称之为复杂配置。

image-20250128225251756

将这个要求不高的称之为简单配置。下面的ClassProxyingConfiguration就是对aop的配置。

修改默认配置

看一下dipatcherServlet的配置类DispatcherServletAutoConfiguration

位置:org\springframework\boot\autoconfigure\web\servlet\DispatcherServletAutoConfiguration.class

最下面有一个有趣的方法,文件上传解析器

@Bean
@ConditionalOnBean({MultipartResolver.class})//检测容器中是否有MultipartResolver类
@ConditionalOnMissingBean(name = {"multipartResolver"}//如果这个类的名字不是multipartResolver
)
public MultipartResolver multipartResolver(MultipartResolver resolver) {return resolver;//修正并返回正确的解析器
}

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

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

相关文章

计算机网络 (60)蜂窝移动通信网

一、定义与原理 蜂窝移动通信网是指将一个服务区分为若干蜂窝状相邻小区并采用频率空间复用技术的移动通信网。其原理在于&#xff0c;将移动通信服务区划分成许多以正六边形为基本几何图形的覆盖区域&#xff0c;称为蜂窝小区。每个小区设置一个基站&#xff0c;负责本小区内移…

17.Word:李楠-学术期刊❗【29】

目录 题目​ NO1.2.3.4.5 NO6.7.8 NO9.10.11 NO12.13.14.15 NO16 题目 NO1.2.3.4.5 另存为手动/F12Fn光标来到开头位置处→插入→封面→选择花丝→根据样例图片&#xff0c;对应位置填入对应文字 (手动调整即可&#xff09;复制样式&#xff1a;开始→样式对话框→管理…

Java面试题2025-并发编程基础(多线程、锁、阻塞队列)

并发编程 一、线程的基础概念 一、基础概念 1.1 进程与线程A 什么是进程&#xff1f; 进程是指运行中的程序。 比如我们使用钉钉&#xff0c;浏览器&#xff0c;需要启动这个程序&#xff0c;操作系统会给这个程序分配一定的资源&#xff08;占用内存资源&#xff09;。 …

Java创建项目准备工作

新建项目 新建空项目 每一个空项目创建好后都要检查jdk版本 检查SDK和语言级别——Apply——OK 检查当前项目的Maven路径&#xff0c;如果已经配置好全局&#xff0c;就是正确路径不用管 修改项目字符集编码&#xff0c;将所有编码都调整为UTF-8 创建Spingboot工程 创建Spring…

2007-2020年各省国内专利申请授权量数据

2007-2020年各省国内专利申请授权量数据 1、时间&#xff1a;2007-2020年 2、来源&#xff1a;国家统计局、统计年鉴 3、指标&#xff1a;行政区划代码、地区名称、年份、国内专利申请授权量(项) 4、范围&#xff1a;31省 5、指标解释&#xff1a;专利是专利权的简称&…

(一)QT的简介与环境配置WIN11

目录 一、QT的概述 二、QT的下载 三、简单编程 常用快捷键 一、QT的概述 简介 Qt&#xff08;发音&#xff1a;[kjuːt]&#xff0c;类似“cute”&#xff09;是一个跨平台的开发库&#xff0c;主要用于开发图形用户界面&#xff08;GUI&#xff09;应用程序&#xff0c;…

【C语言】main函数解析

一、前言 在学习编程的过程中&#xff0c;我们很早就接触到了main函数。在Linux系统中&#xff0c;当你运行一个可执行文件&#xff08;例如 ./a.out&#xff09;时&#xff0c;如果需要传入参数&#xff0c;就需要了解main函数的用法。本文将详细解析main函数的参数&#xff…

自创《艺术人生》浅析

艺术是生活的馈赠&#xff0c;艺术是苦痛的呻吟。 笔记模板由python脚本于2025-01-29 00:01:11创建&#xff0c;本篇笔记适合喜欢写诗读诗诵诗的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述。 …

二进制安卓清单 binary AndroidManifest - XCTF apk 逆向-2

XCTF 的 apk 逆向-2 题目 wp&#xff0c;这是一道反编译对抗题。 题目背景 AndroidManifest.xml 在开发时是文本 xml&#xff0c;在编译时会被 aapt 编译打包成为 binary xml。具体的格式可以参考稀土掘金 MindMac 做的类图&#xff08;2014&#xff09;&#xff0c;下面的博…

AboutDialog组件的功能和用法

文章目录 1 概念介绍2 使用方法3 示例代码 我们在上一章回中介绍了AlertDialog Widget相关的内容,本章回中将介绍AboutDialog Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的AboutDialog是一种弹出式窗口&#xff0c;和上一章回中介绍的Al…

计算机网络 IP 网络层 2 (重置版)

IP的简介&#xff1a; IP 地址是互联网协议地址&#xff08;Internet Protocol Address&#xff09;的简称&#xff0c;是分配给连接到互联网的设备的唯一标识符&#xff0c;用于在网络中定位和通信。 IP编制的历史阶段&#xff1a; 1&#xff0c;分类的IP地址&#xff1a; …

关于产品和技术架构的思索

技术架构或者设计应该和产品设计分离&#xff0c;但是又不应该和产品架构独立。 听起来非常的绕并且难以理解。 下面我们用一个例子来解读这两者的关系 产品&#xff08;族谱图&#xff09; 如果把人类当作产品&#xff0c;那设计师应该是按照上面设计的(当然是正常的伦理道德)…

第十四讲 JDBC数据库

1. 什么是JDBC JDBC&#xff08;Java Database Connectivity&#xff0c;Java数据库连接&#xff09;&#xff0c;它是一套用于执行SQL语句的Java API。应用程序可通过这套API连接到关系型数据库&#xff0c;并使用SQL语句来完成对数据库中数据的查询、新增、更新和删除等操作…

蓝牙技术在物联网中的应用有哪些

蓝牙技术凭借低功耗、低成本和易于部署的特性&#xff0c;在物联网领域广泛应用&#xff0c;推动了智能家居、工业、医疗、农业等多领域发展。 智能家居&#xff1a;在智能家居系统里&#xff0c;蓝牙技术连接各类设备&#xff0c;像智能门锁、智能灯泡、智能插座、智能窗帘等。…

Visual Studio Code修改terminal字体

个人博客地址&#xff1a;Visual Studio Code修改terminal字体 | 一张假钞的真实世界 默认打开中断后字体显示如下&#xff1a; 打开设置&#xff0c;搜索配置项terminal.integrated.fontFamily&#xff0c;修改配置为monospace。修改后效果如下&#xff1a;

开发环境搭建-4:WSL 配置 docker 运行环境

在 WSL 环境中构建&#xff1a;WSL2 (2.3.26.0) Oracle Linux 8.7 官方镜像 基本概念说明 容器技术 利用 Linux 系统的 文件系统&#xff08;UnionFS&#xff09;、命名空间&#xff08;namespace&#xff09;、权限管理&#xff08;cgroup&#xff09;&#xff0c;虚拟出一…

71-《颠茄》

颠茄 颠茄&#xff0c;别名&#xff1a;野山茄、美女草、别拉多娜草&#xff0c;拉丁文名&#xff1a;Atropa belladonna L.是双子叶植物纲、茄科、颠茄属多年生草本&#xff0c;或因栽培为一年生&#xff0c;根粗壮&#xff0c;圆柱形。茎下部单一&#xff0c;带紫色&#xff…

2025 = 1^3 + 2^3 + 3^3 + 4^3 + 5^3 + 6^3 + 7^3 + 8^3 + 9^3

【算法代码】 #include <bits/stdc.h> using namespace std;int year2025; int main() {cout<<year<<" ";int i1;while(year) {cout<<i<<"^3";if(i<9) cout<<" ";year-pow(i,3);i;}return 0; }/* 202…

三天急速通关JavaWeb基础知识:Day 1 后端基础知识

三天急速通关JavaWeb基础知识&#xff1a;Day 1 后端基础知识 0 文章说明1 Http1.1 介绍1.2 通信过程1.3 报文 Message1.3.1 请求报文 Request Message1.3.2 响应报文 Response Message 2 XML2.1 介绍2.2 利用Java解析XML 3 Tomcat3.1 介绍3.2 Tomcat的安装与配置3.3 Tomcat的项…

Baklib揭示内容中台与人工智能技术的创新协同效应

内容概要 在当今信息爆炸的时代&#xff0c;内容的高效生产与分发已成为各行业竞争的关键。内容中台与人工智能技术的结合&#xff0c;为企业提供了一种新颖的解决方案&#xff0c;使得内容创造的流程更加智能化和高效化。 内容中台作为信息流动的核心&#xff0c;能够集中管…