[Spring] Spring原理(SpringBoot完结)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- 1. Bean的作用域
- 1.1 概念
- 1.2 Bean的作用域
- 2. Bean的生命周期
- 2.1 概念
- 2.2 代码演示
- 3. SpringBoot自动配置
- 3.1 Spring加载Bean
- 3.1.1 问题描述
- 3.1.2 原因分析
- 3.1.3 解决方案
- 3.2 SpringBoot原理分析
- 3.2.1 源码
- 3.2.2 @EnableAutoConfiguratio详解
- 3.2.3 总结
1. Bean的作用域
1.1 概念
在我们学习SpringIOC和DI阶段的时候,我们学习了Spring是如何帮助我们管理对象的.
- 首先我们可以通过@Controller ,@Service ,@Repository ,@Component ,@Configuration ,@Bean 来声明Bean对象.
- 通过AppliactionContext(Spring上下文)或者BeanFactory来获取对象.
- 通过@Autowired,Setter方法或者构造方法来为应用程序注入所依赖的Bean对象.
可以通过https://blog.csdn.net/2301_80050796/article/details/140531072?spm=1001.2014.3001.5501这篇文章来复习.
创建一个类,叫做Dog
类.
@Data
@Getter
public class Dog {@Setterpublic Integer age;@Setterpublic String name;
}
之后在DogBeanConfig
类中创建一个对象,之后把对象放入IoC容器中.
@Component
public class DogBeanConfig {@Beanpublic Dog dog(){Dog dog = new Dog();dog.setAge(2);dog.setName("哈士奇");return dog;}
}
之后从上下文中两次拿到dog对象.
@Test
void dogTest(){Dog dog1 = applicationContext.getBean(Dog.class);System.out.println(dog1);Dog dog2 = applicationContext.getBean(Dog.class);System.out.println(dog2);
}
这里我们发现,Bean对象的输出地址是一样的,说明每次从IoC容器中取出来的是同一个对象.
这也就是单例模式,在默认的情况下,Spring中的Bean都是单例的,这种共行为模式,我们就称为Bean的作用域.Bean的作用域指的是Bean在Spring框架中的某种行为模式.
比如单例模式的作用域:表示在整个Spring中,它只有一个,是全局共享的,也就是当有别人修改它的值之后,另一个人读到的就是被修改的值.
@Test@Testvoid dogTest(){Dog dog1 = applicationContext.getBean(Dog.class);dog1.setName("金毛");System.out.println(dog1);System.out.println(dog1.getName());Dog dog2 = applicationContext.getBean(Dog.class);System.out.println(dog2);System.out.println(dog2.getName());}
观察运行结果,我们发现修改之后的Bean对象拿到名字的时候是修改之后的名字.
那么能不能将Bean对象设置为非单例的呢(每次获取Bean对象都是一个新对象)?我们这时候就要提到Bean的作用域了.
1.2 Bean的作用域
在Spring中支持6种作用域,其中后4种在SpringMVC环境中才会生效.
- singleton:单例作用域,表示的是在每个IoC容器中,同名称的Bean只有一个
- prototype:原型作用域(多例作用域),每次使用该Bean的时候,都会创建一个新实例.
- request:请求作用域,每次http请求都会创建一个新的实例
- session:会话作用域,每一个http session周期之内,都会创建一个新实例.
- Application:全局作用域,每个ServletContext生命周期内,创建新的实例
- websocket:HTTPWebSocket作用域,每个WebSocket生命周期内,创建新的实例
指定Bean对象的生命周期,我们可以通过@Scope
(翻译:范围)注解来指定.我们来定义几个作用域不同的Bean.
@Component
public class DogBeanConfig {@Bean@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)public Dog singleDog(){Dog dog = new Dog();dog.setAge(1);dog.setName("萨摩耶");return dog;}@Bean@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)public Dog prototypeDog(){Dog dog = new Dog();dog.setAge(3);dog.setName("柴犬");return dog;}@Bean@RequestScopepublic Dog requestDog(){Dog dog = new Dog();dog.setAge(2);dog.setName("哈士奇");return dog;}@Bean@SessionScopepublic Dog sessionDog(){Dog dog = new Dog();dog.setAge(4);dog.setName("柯基");return dog;}
}
测试不同的Bean获取的对象是否一样.
@RestController
public class DogController {@Autowiredprivate Dog singleDog;@Autowiredprivate Dog prototypeDog;@Autowiredprivate Dog requestDog;@Autowiredprivate Dog sessionDog;@Autowiredprivate ApplicationContext applicationContext;@RequestMapping("/single")public String single(){Dog contextDog = (Dog)applicationContext.getBean("singleDog");return "dog:"+singleDog.toString()+",contextDog:"+contextDog;}@RequestMapping("/prototype")public String prototype(){Dog contextDog = (Dog)applicationContext.getBean("prototypeDog");return "dog:"+prototypeDog.toString()+",contextDog:"+contextDog;}@RequestMapping("/request")public String request(){Dog contextDog = (Dog)applicationContext.getBean("requestDog");return "dog:"+requestDog.toString()+",contextDog:"+contextDog.toString();}@RequestMapping("/session")public String session(){Dog contextDog = (Dog)applicationContext.getBean("sessionDog");return "dog:"+sessionDog.toString()+",contextDog:"+contextDog.toString();}@RequestMapping("/application")public String application(){Dog contextDog = (Dog)applicationContext.getBean("applicationDog");return "dog:"+applicationDog.toString()+",contextDog:"+contextDog.toString();}
}
我们每次请求有两个对象,一个是通过@Autowired
注入的Bean对象,一个是通过上下文获取的Bean对象.
单例作用域:
每一次访问都是同一个对象,并且@Autowired 和applicationContext.getBean() 也是同⼀个对象.
原型作用域:
从上下文获取的Bean对象每一次请求都不一样,但是通过注解注入的Bean对象没有改变,这是由于在项目运行起来之后就已经注入完成了,所以多次请求也不会发生变化.
请求作用域:
每一次请求中,@Autowired
和applicationContext.getBean()
也是同⼀个对象.每次请求都会创建一个新对象.
会话作用域:
在一个session中,多次请求,获取到的对象都是同一个.换一个浏览器访问就会重新创建对象.
Appliaction作用域:
在⼀个应用中,多次访问都是同⼀个对象
这个Appliaction的效果和Singleton有些类似,但是他们有所不同,区别在于:Application scope是ServletContext的单例,singleton是⼀个ApplicationContext的单例.在⼀个web容器中ApplicationContext可以有多个,但是一个web容器中只有一个ServletContext容器.(了解)
2. Bean的生命周期
2.1 概念
生命周期指的是一个对象从诞生到销毁的过程.
Bean的生命周期分为一下5个部分:
- 实例化(为Bean分配内存空间) —> 构造方法
- 属性赋值(Bean注入和装配,比如
@Autowired
) —> Setter方法注入 - 初始化: 就是执行通知,
BeanNameAware
,BeanFactoryAware
,ApplicationContextAware
的接口方法和执行使用注解@PostConstruct
修饰的初始化方法. - 使用Bean.
- 销毁Bean: 就是执行销毁容器
DisposableBean
接口方法和执行使用注解@PreDestroy
修饰的销毁容器的方法.
这个就好比我们想买一套房子:
- 需要先买房(实例化,分配内存空间)
- 装修,把毛坯房变为精装房(执行属性赋值,执行@Autowired注入赋值)
- 购买家电.(执行初始化方法,包括接口实现和注释修饰)
- 拎包入住(使用Bean)
- 寿命到期,拆迁(销毁Bean)
2.2 代码演示
@Component
public class BeanLifeComponent implements BeanNameAware {private Dog dog;public BeanLifeComponent(){System.out.println("实例化Bean...");}@Autowiredpublic void setDog(Dog dog1) {//set方法注入法this.dog = dog1;System.out.println("属性赋值Bean");}@Overridepublic void setBeanName(String name) {System.out.println("执行了BeanNameAware接口的通知方法(初始化Bean)");}@PostConstructpublic void init(){System.out.println("执行了PostConstruct注解修饰的方法(初始化Bean)");}public void use(){System.out.println("使用Bean");}@PreDestroypublic void destroy(){System.out.println("销毁Bean");}
}
测试代码:
@Test
void beanLifeComponent(){BeanLifeComponent beanLifeComponent = applicationContext.getBean(BeanLifeComponent.class);beanLifeComponent.use();
}
测试结果如下:
即使类中的这些方法变换了顺序,也不会改变这些这些内容输出的顺序.
3. SpringBoot自动配置
SpringBoot的自动配置就是当Spring容器启动后,⼀些配置类,bean对象等就自动存入到了IoC容器中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作.
3.1 Spring加载Bean
3.1.1 问题描述
现在有一个问题,就是属于Spring本身的类自动导入还可以理解,但是如果是第三方的库想要导入Spring是如何做到的呢?
现在我们使用在项目下创建不同的目录来模拟第三方代码的引入.
数据准备:
- 在
com.jrj.springprincipledemo
软件包之外新创建一个软件包spring_autoconfig
,之后在spring_autoconfig
引入第三方代码TestConfig
.
@Component
public class TestConfig {public void print(){System.out.println("打印...");}
}
- 在
com.jrj.springprincipledemo
目录下的运行类中通过上下文来获取这个Bean对象,我们发现是获取不到的.
@SpringBootApplication
public class SpringPrincipleDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringPrincipleDemoApplication.class, args);TestConfig testConfig = context.getBean(TestConfig.class);System.out.println(testConfig);}
}
3.1.2 原因分析
根据前面学过的知识,我们知道,这是由于启动项只能扫描到他所在的目录以及子目录造成的,而在外面的目录却扫描不到.
当我们引入第三方的jar包的时候,第三方jar代码目录一定不再启动类的目录下,那么如何告诉Spring帮我们管理这些Bean呢?
3.1.3 解决方案
我们需要指定路径或者引入文件,告诉Spring,Spring扫描到.
常见的解决方案有两种:
@ComponentScan
注解添加扫描路径.
这种方法我们之前在SpringIoC&DI注入介绍过,不再赘述@Import
注解导入
@Import
导入形式主要有以下两种:- 导入类
@SpringBootApplication
@Import(TestConfig.class)
public class SpringPrincipleDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringPrincipleDemoApplication.class, args);TestConfig testConfig = context.getBean(TestConfig.class);System.out.println(testConfig);}
}
我们看到了启动类成功拿到了IoC容器中的Bean对象.
也可以使用大括号导入多个类:@Import({TestConfig1.class,TestConfig2.class})
- 导入ImportSelector
接口实现类.
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"spring_autoconfig.TestConfig"};}
}
需要注意的一点是,给返回值导入类的时候,需要导入类的全限定名称.
在启动类的上面直接导入实现ImportSelector
的类.
@SpringBootApplication
@Import(MyImportSelector.class)
public class SpringPrincipleDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringPrincipleDemoApplication.class, args);TestConfig testConfig = context.getBean(TestConfig.class);System.out.println(testConfig);}
}
依然可以获取到对象:
问题:但是他们都有⼀个明显的问题,就是使用者需要知道第三方依赖中有哪些Bean对象或配置类.依赖中有哪些Bean,使用的时候需要配置哪些Bean,只有第三方最清楚,能否让第三方来做这件事情呢?
- 比较常见的方案就是第三方依赖给我们提供一个注解,这个注解一般都是以
@EnableXxxx
开头,其中封装的就是@Import
注解.- 第三方提供注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(TestConfig.class)
public @interface EnableTestConfig {
}
使用@Target
标签定义注解在哪里标记,使用@Retention
注解定义注解的生命周期.之后使用@Import
注解导入第三方的类对象.
2. 在启动类上提供第三方注解
@SpringBootApplication
@EnableTestConfig
public class SpringPrincipleDemoApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(SpringPrincipleDemoApplication.class, args);TestConfig testConfig = context.getBean(TestConfig.class);System.out.println(testConfig);}
}
Bea对象依然可以拿到:
3.2 SpringBoot原理分析
3.2.1 源码
那么Spring究竟是如何实现自动导入的呢?接下来我们就来查看Spring的源码,我们从@SpringBootApplication
开始看起.
这个直接也是Spring实现自动配置的核心
@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 {
....
}
@SpringBootAppliaction
是一个组合注解,注解中包含了:
- 元注解:
JDK中提供了4个标准的用来对注解类型进行注解的注解类,我们称之为meta-annotation(元注解),他们分别是:
• @Target描述注解的使用范围(即被修饰的注解可以用在什么地方)
• @Retention描述注解保留的时间范围
• @Documented描述在使用javadoc工具为类生成帮助文档时是否要保留其注解信息(了解)
• @Inherited使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,其子类自动具有该注解) - @SpringBootConfiguration:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;
}
里面其实就是一个@Configuration
,只不过就是封装了一层而已.
3. @EnableAutoConfiguratio
这是Spring自动装配的核心机制,下面详细解释.
4. @ComponentScan
excludeFilter是自定义过滤器,通常用于排除一些类,注解等.
3.2.2 @EnableAutoConfiguratio详解
我们来观察@EnableAutoConfiguration
注解的实现:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {/*** Environment property that can be used to override when auto-configuration is* enabled.*/String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";/*** Exclude specific auto-configuration classes such that they will never be applied.* @return the classes to exclude*/Class<?>[] exclude() default {};/*** Exclude specific auto-configuration class names such that they will never be* applied.* @return the class names to exclude* @since 1.3.0*/String[] excludeName() default {};}
这个注解主要包含两部分:
- @Import(AutoConfigurationImportSelector.class)
使用@Import注解,导入实现ImportSelector的类
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered{@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return NO_IMPORTS;}AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}}
selectImports
方法有调用了getAutoConfigurationEntry
方法,获取可以自动配置的配置类信息集合:
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {if (!isEnabled(annotationMetadata)) {return EMPTY_ENTRY;}AnnotationAttributes attributes = getAttributes(annotationMetadata);List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);configurations = removeDuplicates(configurations);Set<String> exclusions = getExclusions(annotationMetadata, attributes);checkExcludedClasses(configurations, exclusions);configurations.removeAll(exclusions);configurations = getConfigurationClassFilter().filter(configurations);fireAutoConfigurationImportEvents(configurations, exclusions);return new AutoConfigurationEntry(configurations, exclusions);}
其中getCandidateConfigurations
方法获取在配置文件中所有自动配置类的集合.
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).getCandidates();Assert.notEmpty(configurations,"No auto configuration classes found in "+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}
获取的是所有基于META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
配置文件和META-INF/spring.factories
的配置文件.里面包含了很多第三方依赖的配置文件.
[注意]
- 加载的时候并不是把所有的配置全部加载进来,他是根据不同的条件来导入对应的配置的,这和
@Conditional
注解有关系,这个注解是Spring底层的一个注解,就是根据不同的条件来进行自己不同条件的判断,如果满足指定的条件,配置才会生效. - META-INF/spring.factories文件是Spring内部提供的⼀个约定俗成的加载方式,只需要在模块的META-INF/spring.factories文件中配置即可, Spring就会把相应的实现类注入到Spring容器中.
- @AutoConfigurationPackage
源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {String[] basePackages() default {};Class<?>[] basePackageClasses() default {};}
这个注解主要是导入了配置文件AutoConfigurationPackages.Registrar.class
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));}@Overridepublic Set<Object> determineImports(AnnotationMetadata metadata) {return Collections.singleton(new PackageImports(metadata));}}
Registrar中实现了ImportBeanDefinitionRegistrar
类,就可以被注解@Import
导入到Spring容器中.其中PackageImports(metadata).getPackageNames().toArray(new String[0]))
就是当前启动所在的包名.
所以:@AutoConfigurationPackage
就是把启动类所在的包下面所有的组件全部都扫描注册操Spring容器中.
3.2.3 总结
SpringBoot自动装配原理大致如下:
当Spring项目启动的时候,就会自动把这些配置文件中的配置类通过@Import
注解全部加载到SpringIoC容器中.
相关文章:

[Spring] Spring原理(SpringBoot完结)
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
python | rq,一个无敌的 关于Redis 的Python 库!
本文来源公众号“python”,仅用于学术分享,侵权删,干货满满。 原文链接:rq,一个无敌的 Python 库! 大家好,今天为大家分享一个无敌的 Python 库 - rq。 Github地址:https://githu…...

Redis的缓存淘汰策略
1. 查看Redis 最大的占用内存 打开redis配置文件, 设置maxmemory参数,maxmemory 是bytes字节类型, 注意转换 2. Redis默认内存多少可以用 注意: 在64bit系统下, maxmemory 设置为 0 表示不限制Redis内存使用 3. 一般生产上如何配置 一般推荐Redis 设置内…...

【C++】深度解析:用 C++ 模拟实现 priority_queue类,探索其底层实现细节(仿函数、容器适配器)
目录 ⭐前言 ✨堆 ✨容器适配器 ✨仿函数 ⭐priority_queue介绍 ⭐priority_queue参数介绍 ⭐priority_queue使用 ⭐priority_queue实现 ✨仿函数实现 ✨堆的向上调整和向下调整 ✨完整代码 ⭐前言 ✨堆 堆是一种特殊的树形数据结构,通常以二叉树的…...

1个人躲,5个人抓!《极限竞速:地平线5》全新游戏模式“捉迷藏”即将推出
风靡全球的赛车竞速游戏《极限竞速:地平线5》即将推出全新游戏模式——捉迷藏(Hide & Seek)。 《极限竞速:地平线5》日前发布了全新预告,展示了即将于 9 月 10 日推出的捉迷藏模式游戏玩法。该预告是日前举办的2024 年科隆国际游戏展 Xb…...

ARCGIS XY坐标excel转要素面
1、准备好excel 坐标 excel文件转为csv才能识别,CSV只能保留第一个工作表并且,不会保留格式。 2、在ArcGis中导入XY事件图层 创建XY事件图层 图层要素赋对象ID 将导入的图层导出为先新的图层,这样就给每个要素附加了唯一的值 选择点集转线…...

MyBatis源码系列3(解析配置文件,创建SqlSessionFactory对象)
创建SqlSessionFactory; 首先读取配置文件,使用构造者模式创建SqlSessionFactory对象。 InputStream inputStream Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder…...

企业级web应用服务器tomcat
目录 一、Web技术 1.1 HTTP协议和B/S 结构 1.2 前端三大核心技术 1.2.1 HTML 1.2.2 CSS(Cascading Style Sheets)层叠样式表 1.2.3 JavaScript 二、tomcat的功能介绍 2.1 安装 tomcat 环境准备 2.1.1 安装java环境 2.1.2 安装并启动tomcat …...

深入浅出,探讨IM(即时通讯-聊天工具)技术架构及用户界面设计
在数字化时代的浪潮中,即时通讯(IM)工具已然成为人们日常沟通的重要方式。从微信、QQ到飞信钉、喧喧IM、企业微信、钉钉、Slack,这些IM工具不仅为我们提供了便捷的沟通方式,更在技术架构和用户界面设计上展现了独特的魅…...

小米、友邦带领恒指大反攻!
港股三大指数反弹止步2连跌,恒生科技指数一度冲高至2%,恒指收涨1.44%。盘面上,大型科技股多数表现活跃,业绩超预期,小米大涨超8%表现尤其抢眼,京东涨约4%,百度涨1.71%,网易涨2.14%&a…...

中国植物性状数据库
中国植物性状的研究主要集中在植物的生理结构和功能,以及它们对环境的适应性上。中国植物性状的多样性体现在多个方面,包括植物的生理结构、生长习性、以及对环境的适应性等。 中国植物性状数据库,包含了来自140个样点的1529种植物…...

[数据集][目标检测]街灯路灯检测数据集VOC+YOLO格式1893张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):1893 标注数量(xml文件个数):1893 标注数量(txt文件个数):1893 标注…...
C++位运算
C位运算 运算符 & 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 | 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1 ^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1 ~ 取反 ~是一元…...

Day97:云上攻防-云原生篇KubernetesK8s安全APIKubelet未授权访问容器执行
知识点: 1、云原生-K8s安全-名词架构&各攻击点 2、云原生-K8s安全-Kubelet未授权访问 3、云原生-K8s安全-API Server未授权访问 K8S集群 Kubernetes是一个开源的,用于编排云平台中多个主机上的容器化的应用,目标是让部署容器化的应用…...

招聘|头部云厂商招 PG 核心骨干 DBA【上海】
我们的招聘专区又回来了!🏃 Bytebase 作为先进的数据库 DevOps 团队协同工具 🔧,用户群里汇聚了 💗 业界优秀的 DBA,SRE,运维的同学们 🌟。 上周用户群里有小伙伴发招聘信息 &…...

继承(下)【C++】
文章目录 子类继承父类之后,子类的默认成员函数的变化构造函数编译器自动生成的构造函数程序员手动写的构造函数 拷贝构造编译器自动生成的拷贝构造函数程序员手动写的拷贝构造函数 赋值重载编译器自动生成的赋值重载程序员手动写的赋值重载 析构函数 继承与友元菱形…...

AI模拟器
一、介绍 基于鸿蒙Next模拟一个ai对话过程二、场景需求 客户服务、数据分析、个性化推荐、图像和视频处理、智能家居、交通管理、教育行业、制造等等。 三、业务步骤 第一步:输入框提出问题,发送问题, 第二部:下次发送࿰…...

【C++二分查找 前缀和】1658. 将 x 减到 0 的最小操作数
本文涉及的基础知识点 C二分查找 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 LeetCode1658. 将 x 减到 0 的最小操作数 给你一个整数数组 nums 和一个整数 x 。每一次操作时,你应当移除数组 nums 最左边或最右边的元素&am…...

验证实战知识点--(2)
1.seq中的pre_start pre_start 是 uvm_sequence 类的一个虚拟方法,用于在序列开始执行之前进行初始化和设置。这个方法在调用 start 方法前立即执行,提供了一个执行自定义初始化代码的机会。 start 方法用于启动序列的执行,而 pre_start 可以…...

【图文并茂】ant design pro 如何优雅地把删除和批量删除功能合并到一起,并抽出来成为组件
如上图所示,其实批量删除和删除应该算是一个功能 只是删除一个或多个的区别 那么接口应该用的同一个 删除一个的时候呢,就传 一个对象_id 过去 删除多个的时候,就传 多个 对象 _id 的数组过去 后端 const deleteMultipleRoles handleAs…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
React Native 导航系统实战(React Navigation)
导航系统实战(React Navigation) React Navigation 是 React Native 应用中最常用的导航库之一,它提供了多种导航模式,如堆栈导航(Stack Navigator)、标签导航(Tab Navigator)和抽屉…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...