spring高级篇(十)
1、内嵌tomcat
boot框架是默认内嵌tomcat的,不需要手动安装和配置外部的 Servlet 容器。
简单的介绍一下tomcat服务器的构成:
- Catalina: Catalina 是 Tomcat 的核心组件,负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包括一个 Web 容器和一个 Servlet 引擎,用于处理 Servlet 和 JSP 页面。
- Connector: 连接器是 Tomcat 与外部客户端之间通信的桥梁,负责处理传入的 HTTP 请求,并将其传递给 Catalina 处理。Tomcat 提供了多种类型的连接器,包括 HTTP 连接器(用于处理 HTTP 请求)、AJP 连接器(用于与 Apache HTTP Server 连接)等。
- Realm: Realm 是 Tomcat 的安全认证和授权机制,用于验证用户身份并控制用户对受保护资源的访问权限。Tomcat 支持多种类型的 Realm,如基于内存的 Realm、基于数据库的 Realm 等。
- Valves: 阀门是 Tomcat 的拦截器组件,用于在请求处理过程中执行特定的操作,如访问日志记录、安全验证、压缩等。Tomcat 提供了多种类型的阀门,可以通过配置文件进行灵活配置。
- Host: Host 是 Tomcat 的虚拟主机,用于在同一物理服务器上托管多个域名或应用程序。每个 Host 都有一个唯一的名称和基础目录,可以配置不同的域名和应用程序。
- Engine: Engine 是 Tomcat 的引擎,用于管理多个虚拟主机(Host)。它负责调度请求到相应的虚拟主机,并协调虚拟主机之间的资源共享和管理。
- Context: Context 是 Tomcat 的上下文容器,用于管理和配置单个 Web 应用程序的运行环境。每个 Web 应用程序都有一个对应的 Context,包括其配置信息、Servlet 映射、Session 管理等。
我们来模拟一下tomcat的执行过程:
其中第四步是将下面自定义的servlet程序放入servletContext上下文中,并且手动指定映射路径(相当于Controller层加入@RequestMapping及派生注解指定路径)
public class A36 {public static void main(String[] args) throws IOException, LifecycleException {//1.创建tomcat对象Tomcat tomcat = new Tomcat();tomcat.setBaseDir("tomcat");//准备docBase,存放项目文件File docBase = Files.createTempDirectory("boot.").toFile();docBase.deleteOnExit();//3.创建tomcat项目 contextContext context = tomcat.addContext("", docBase.getAbsolutePath());//4.编程添加servletcontext.addServletContainerInitializer(new ServletContainerInitializer() {@Overridepublic void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {servletContext.addServlet("test",new MyServlet()).addMapping("/test");}}}, Collections.emptySet());//5.启动tomcattomcat.start();//6.设置协议,创建连接器Connector connector = new Connector(new Http11Nio2Protocol());connector.setPort(8080);tomcat.setConnector(connector);}
}
编写一个自定义的servlet程序:
public class MyServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().print("abc");}
}
而内嵌的tomcat如何与Spring进行整合?
其关键点在于Config配置类中的 public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) 方法。这个方法用于注册DispatcherServlet springmvc入口并创建一个 DispatcherServletRegistrationBean Bean,将传入的 DispatcherServlet 注册到 Spring 应用程序中。
Config配置类又是在refresh容器前注册的:
public static WebApplicationContext webApplicationContext(){AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();context.register(Config.class);context.refresh();return context;}
我们只需要在编程添加servlet这一步,获取容器中所有的bean,并且通过.onStartup() 方法完成注册:
//得到applicationContextWebApplicationContext applicationContext = webApplicationContext();//4.编程添加servletcontext.addServletContainerInitializer(new ServletContainerInitializer() {@Overridepublic void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {servletContext.addServlet("test",new MyServlet()).addMapping("/test");//得到ServletRegistrationBean中每一个注册的beanfor (ServletRegistrationBean value : applicationContext.getBeansOfType(ServletRegistrationBean.class).values()) {value.onStartup(servletContext);}}}, Collections.emptySet());
.onStartup() 方法底层调用的依旧是 servletContext.addServlet() 方法
boot在整合tomcat时,首先是创建了Spring容器,然后在调用onfresh()方法时会将tomcat创建出来,并且执行到添加servlet。
在finishRefresh(); 方法会启动tomcat服务器并且设置协议,创建连接器。
2、自动装配原理
现在有如下的场景:在某个包下创建了两个bean,并且将其注册到了两个配置类中:
public class Bean1 {}
public class Bean2 {
}
@Configuration
public class Config1 {@Beanpublic Bean1 bean1(){return new Bean1("第三方");}
}
@Configuration
public class Config2 {@Beanpublic Bean2 bean2(){return new Bean2();}
}
假设这两个bean都是与数据库连接有关的组件,具有通用性。那么难道是每次在别的地方用到的时候,都去临时注册吗?答案肯定是否定的,就和方法封装一样,我们可以在其他运用到的地方进行导入:
@Import 注解的作用就是导入其他配置类或组件类,如果在 @Import 注解中将Config1和Config2 的class 写死,这样不太好:
@Configuration
@Import(MyInportSelector.class)
public class MyConfig {@Beanpublic Bean1 bean1(){return new Bean1("本项目");}
}
我们可以将Config1和Config2注册在自定义的MyInportSelector类中统一管理:
在Spring中,某个自定义ImportSelector类下需要统一装配的组件,不是写死在自定义ImportSelector类中的,而是放在META-INF下的spring.factories中统一进行管理。
/*** 读取配置文件中的引用*/
public class MyInportSelector implements ImportSelector {/*** 在方法中会读取所有jar包 META-INF下的spring.factories 做自动装配* @param importingClassMetadata* @return*/@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {//需要自动装配的类不是写死在代码中的,而是放在配置文件中的//从配置文件中读取信息 META-INF下的spring.factories//com.itbaima.a37.MyInportSelector=\//com.itbaima.a37_1.Config1,\//com.itbaima.a37_1.Config2List<String> strings = SpringFactoriesLoader.loadFactoryNames(MyInportSelector.class, null);return strings.toArray(new String[0]);}
}
完成EnableAutoConfiguration的自动装配:
/*** 读取配置文件中的引用*/
public class MyInportSelector implements ImportSelector {/*** 在方法中会读取所有jar包 META-INF下的spring.factories 做自动装配* @param importingClassMetadata* @return*/@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {for (String name : SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class, null)) {System.out.println(name);}}
}
那如果在本项目注册的bean和其他外部引用的bean同名的问题呢?
生效的是本项目中的。因为bean加载的时机不同,第三方的bean先加载,后加载的bean会覆盖先加载的同名的bean。然而在boot中默认是false不允许覆盖。解决方法:
自定义的InportSelector实现DeferredImportSelector接口,可以推迟第三方bean的加载。并且需要在注册第三方bean时加上 @ConditionalOnMissingBean 注解,表明当容器中没有该名称的bean时才需要加载。(因为此时本项目中的bean已先于第三方的bean加载)
@Configuration
public class Config1 {@Bean@ConditionalOnMissingBean//当容器中缺少某个bean时才会添加public Bean1 bean1(){return new Bean1("第三方");}
}
3、AopAutoConfiguration
AopAutoConfiguration是用于负责配置和启用 AspectJ 面向切面编程(AOP)功能。
我们模拟一下它的自动装配:
@Configuration
@Import(MyImportSelector.class)
public class Config {
}
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{AopAutoConfiguration.class.getName()};}
}
public class A38 {public static void main(String[] args) {GenericApplicationContext context = new GenericApplicationContext();//注册各种后处理器AnnotationConfigUtils.registerAnnotationConfigProcessors(context.getDefaultListableBeanFactory());context.registerBean(Config.class);context.refresh();for (String name : context.getBeanDefinitionNames()) {System.out.println(name);}}
}
下面这四条便是AopAutoConfiguration通过自动装配得到的BeanDefinitionName
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$AspectJAutoProxyingConfiguration$CglibAutoProxyConfiguration
org.springframework.aop.config.internalAutoProxyCreator
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration$AspectJAutoProxyingConfiguration
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration
那么AopAutoConfiguration是如何选择装配哪些bean的呢?我们点进AopAutoConfiguration的源码看一下:
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) 是一个针对properties配置文件内容的判断,此处判断的含义是,如果配置文件中没有spring.aop前缀的键,或者有并且它的值为true时,会进入这个类。显然目前的条件是成立的,我们自定义的配置类中没有spring.aop前缀的键。
在静态内部类AspectJAutoProxyingConfiguration上也有一个注解:@ConditionalOnClass(Advice.class) 作用是判断是否存在一个名为Advice的类,在boot中是存在的,所以会进入AspectJAutoProxyingConfiguration类:
在JdkDynamicAutoProxyConfiguration和CglibAutoProxyConfiguration静态内部类上,分别有两个注解:
- @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false") 判断properties配置文件中是否有spring.aop前缀的键,并且值要为false。
- @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) 判断properties配置文件中是否有spring.aop前缀的键,并且值要为ture,或者不存在。
而两个静态内部类上标注的@EnableAspectJAutoProxy 注解,实际上也是加上了@Import
注解的自动装配配置类:
自定义的自动装配了类实现了ImportBeanDefinitionRegistrar接口,用于用编程的方式确定装配的内容:
在AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); 方法中,实际上是注册了AnnotationAwareAspectJAutoProxyCreator:
复习一下(第三篇):AnnotationAwareAspectJAutoProxyCreator是用于自动创建代理以实现切面功能的Spring后处理器,将高级的Aspect切面分解并转换成低级的Advice切面,并且根据设置去选择JDK或CGLIB代理方式(proxyTargetClass属性),在AnnotationAwareAspectJAutoProxyCreator中,有两个重要的方法:
- protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName):用于查找符合条件的切面通知器(Advisors)。
- protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey):内部调用 .findEligibleAdvisors得到存放符合条件切面通知器的集合,如果集合不为空,就创建代理。
根据条件,应该会自动装配CglibAutoProxyConfiguration:
可从容器中获取AnnotationAwareAspectJAutoProxyCreator,isProxyTargetClass的取值是true,代表无论是否实现了接口,走的都是CGLIB代理方式。
AnnotationAwareAspectJAutoProxyCreator proxyCreator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
System.out.println(proxyCreator.isProxyTargetClass());
4、DataSource
在DataSourceAutoConfiguration中,主要有两部分:
- EmbeddedDatabaseConfiguration:Spring Framework 中用于配置内嵌式数据库(Embedded Database)的自动配置类之一
- PooledDataSourceConfiguration:Spring Framework 中用于配置连接池数据源(Pooled DataSource)的自动配置类之一。
EmbeddedDatabaseConfiguration很少用到,我们重点看PooledDataSourceConfiguration:
DataSourceConfiguration的每个静态内部类上都加入了@ConditionalOnClass 条件判断注解。
Boot中默认是有HikariDataSource源的:
所以会将HikariDataSource注册成bean并设置连接信息:
5、MybatisAutoConfiguration
在MybatisAutoConfiguration类上,有如下的注解:
- @ConditionalOnClass({SqlSessionFactory.class, SqlSessionFactoryBean.class}) :表明必须要存在SqlSessionFactory和SqlSessionFactoryBean两个类。因为mybatis与boot整合需要数据源连接信息。
- @ConditionalOnSingleCandidate(DataSource.class) :表明数据源必须是唯一的,不能存在多份不同的数据源
- @EnableConfigurationProperties({MybatisProperties.class}) : 表明将来会创建一个MybatisProperties对象,用于将环境中的键值信息与对象绑定(要求配置中的键名必须前缀mybatis):
- @AutoConfigureAfter({ DataSourceAutoConfiguration.class, MybatisLanguageDriverAutoConfiguration.class }) : 表明该配置类是在DataSourceAutoConfiguration、MybatisLanguageDriverAutoConfiguration加载完成后再进行初始化。
上述任何一个条件不满足都不会进入MybatisAutoConfiguration:
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) 方法用于创建SqlSessionFactory的bean,注意加上了@ConditionalOnMissingBean 代表容器中没有其他第三方的SqlSessionFactory的bean时,才会初始化MybatisAutoConfiguration中的SqlSessionFactory。
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) 方法用于创建SqlSession模板:
SqlSessionTemplate是线程安全的,在同一个线程中,不同方法可以共用一个实例。
最后还有一个MapperScannerRegistrarNotFoundConfiguration内部类:
它只有在没有自定义的MapperFactoryBean和MapperScannerConfigurer时才会生效:
然后通过@Import(AutoConfiguredMapperScannerRegistrar.class) 注解导入了AutoConfiguredMapperScannerRegistrar,作用是扫描和引导类同包下的被@Mapper注解控制的mapper/dao接口,将这些定义为bean
6、DataSourceTransactionManagerAutoConfiguration
DataSourceTransactionManagerAutoConfiguration是用于自动配置数据源事务管理器(DataSource Transaction Manager)的类之一。
- 在类上标注了@ConditionalOnClass({ JdbcTemplate.class, TransactionManager.class }) 注解,要求必须要有事务管理器和JDBC模板方法。
- @EnableConfigurationProperties(DataSourceProperties.class) 会将配置文件中以spring.datasource为前缀的key绑定到DataSourceProperties对象中(设置数据库连接信息,username,password...)
并且导入了EnableConfigurationPropertiesRegistrar自动装配类。
同样JdbcTransactionManagerConfiguration静态内部类限定容器中只能有一份数据源:
- DataSourceTransactionManager:创建处理与JDBC 数据源相关的事务的Bean。
下面介绍一些与整合Spring MVC相关的配置类:
7、TransactionAutoConfiguration
TransactionAutoConfiguration 是用于自动配置事务管理的类之一。
- @ConditionalOnClass(PlatformTransactionManager.class) 表明容器中必须要有PlatformTransactionManager类,简单来说,它定义了事务管理器的核心功能。
- @AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class }) 表明TransactionAutoConfiguration是在@AutoConfigureAfter 注解value中的类初始化成后再加载。
- @EnableConfigurationProperties(TransactionProperties.class) 可以将配置文件中以spring.transaction为前缀的key绑定到TransactionProperties对象上。
并且导入了EnableConfigurationPropertiesRegistrar自动装配类
TransactionAutoConfiguration类中,提供了声明式和响应式事务的支持:
以及创建事务管理器:
还有配置声明式事务的管理:
8、ServletWebServerFactoryAutoConfiguration
是 Spring Boot 中负责配置 Servlet 容器工厂的自动配置类之一:
- @ConditionalOnClass(ServletRequest.class):ServletRequest类存在,条件成立。(ServletRequest定义了客户端向服务器发送的 HTTP 请求的主要属性和操作。它是一个核心组件,用于在服务器端处理 HTTP 请求,HttpServletRequest就是它的子类)
- @ConditionalOnWebApplication(type = Type.SERVLET) :应用程序是一个 Servlet Web 应用程序时,条件成立
- @EnableConfigurationProperties(ServerProperties.class):用于启用特定类型的配置属性绑定到ServerProperties对象中。
这个类中主要注册了两个Bean:
- ServletWebServerFactoryCustomizer:这个方法的主要作用是根据传入的参数定制 Servlet Web 服务器工厂的行为,包括配置服务器属性、注册 Web 监听器以及处理 Cookie 的 SameSite 属性。
- TomcatServletWebServerFactoryCustomizer:这个方法的主要作用是根据传入的参数定制 Tomcat Servlet Web 服务器的行为,包括配置服务器属性、Session 会话管理、安全性等方面。
9、DispatcherServletAutoConfiguration
用于配置和启用 DispatcherServlet。DispatcherServlet 是 Spring MVC 中的中央调度器,用于处理传入的 HTTP 请求,并将它们分发到相应的处理程序(Controller)进行处理:
- @ConditionalOnWebApplication(type = Type.SERVLET) :应用程序是一个 Servlet Web 应用程序时,条件成立
- @ConditionalOnClass(DispatcherServlet.class) :容器中必须包含DispatcherServlet类,条件成立
- @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class :在ServletWebServerFactoryAutoConfiguration类装配完成后( Servlet 容器工厂创建完成),装配本类。
在这个类中,较为重要的是DispatcherServletConfiguration和DispatcherServletRegistrationConfiguration两个静态内部类:
- DispatcherServletConfiguration:主要是将DispatcherServlet注册成bean,以及一个解析客户端发送的包含文件上传的 HTTP 请求,并将上传的文件转换成可操作的对象的bean
- DispatcherServletRegistrationConfiguration:主要作用是将DispatcherServletRegistrationBean注册成bean,并且设置tomcat容器启动时即进行DispatcherServlet初始化
10、WebMvcAutoConfiguration
主要用于配置和初始化 Spring MVC 的各种组件:
RequestMappingHandlerAdapter:
RequestMappingHandlerMapping:
ExceptionHandlerExceptionResolver:
11、ErrorMvcAutoConfiguration
主要作用是在应用程序启动时,自动配置一些默认的错误处理策略和错误页面。
此前提到的BasicErrorController(处理基本的错误页面和错误信息),ErrorPageRegistrar(转发到自定义的错误页面),在本类中都有体现:
相关文章:

spring高级篇(十)
1、内嵌tomcat boot框架是默认内嵌tomcat的,不需要手动安装和配置外部的 Servlet 容器。 简单的介绍一下tomcat服务器的构成: Catalina: Catalina 是 Tomcat 的核心组件,负责处理 HTTP 请求、响应以及管理 Servlet 生命周期。它包…...

map、set底层封装模拟实现(红黑树)
文章目录 一、红黑树1.1红黑树的规则:1.2红黑树的插入操作1.2.1不需要旋转(如果叔叔存在且为红,这里的C表示孩子,P表示父亲,U表示叔叔,G表示祖父),包含四种情况,无论孩子在哪里&…...
PHP8.2-xlswriter 扩展
https://pecl.php.net/package/xlswriter ### 进入/root/ cd ~ ### 下载扩展 wget https://pecl.php.net/get/xlswriter-1.5.5.tgz ### 解压扩展 tar -zxvf xlswriter-1.5.5.tgz ### 进入扩展目录 cd xlswriter-1.5.5 ### 查找对应php版本的phpize find / -name phpi…...
imx6ull开发板设置SD卡启动,SD卡中烧写uboot,kernel,设备树,根文件系统fs
IMX6ULL ARM Linux开发板SD卡启动,SD卡的分区与分区格式化创建_sd制作分区-CSDN博客...

2024年第七届可再生能源与环境工程国际会议(REEE 2024)即将召开!
2024年第七届可再生能源与环境工程国际会议(REEE 2024)将于2024 年8月28-30日在法国南特举行。共绘绿色未来,全球同频共振!REEE 2024将汇聚全球可再生能源与环境工程领域的专家学者和业界精英,共同探讨行业发展的前沿技…...

【华为】NAT的分类和实验配置
【华为】NAT的分类和实验配置 NAT产生的技术背景IP地址分类NAT技术原理NAT分类静态NAT动态NATNAPTEasy IP(PAT)NAT Server 配置拓扑静态NAT测试抓包 动态NAT测试抓包 NAPT测试抓包 PAT测试抓包 NAT Server检测抓包 PC1PC2服务器 NAT产生的技术背景 随着…...

拉普拉斯丨独家冠名2024年度ATPV技术分论坛,助力产业科技持续创新
为了进一步促进行业技术交流,推进光伏行业发展及标准建设的进程,针对高效电池,领跑组件,新产品认证及应用等技术专题及国内外光伏标准的最新进程,由中国绿色供应链联盟光伏专委会(ECOPV)指导的2…...
LangChain入门教程 - 使用代理Agent
对于大模型,比如某些场景,需要数学计算,或者需要从某些网站获取参考资料,就必须使用专门的代理来完成任务。这里我们使用langchain提供的数学工具来实现一个最简单的例子,下一篇我们会讲如何自己实现代理。 首先创建一…...
windows驱动开发-内核编程技术汇总(五)
使用安全字符串函数 和应用层不一样的是,windows内核完全使用Unicode字符串,许多支持AsciiC的windowsAPI,是在应用层完成项Unicode的切换的。许多系统安全问题是由缓冲区处理不善和生成的缓冲区溢出引起的。 糟糕的缓冲区处理通常与字符串操…...
Java中的optional类是啥和例子
Optional 是 Java 8 引入的一个容器对象,用于表示值存在或不存在。这是一个可以为 null 的容器对象,但使用 Optional 比直接使用 null 更安全,因为 Optional 类提供了许多有用的方法,以便更优雅地处理可能存在或不存在的值。 使用…...

AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA
系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据集概…...
mysql事务锁排查
-- mysql show full PROCESSLIST; -- 查看哪些表在锁。 show open tables where IN_use>0; -- 正在执行的事务: SELECT * FROM information_schema.INNODB_TRX;-- 8.0之前 查看正在锁的事务 select * from information_schema.innodb_locks;-- 查看等待锁的事务 …...

ChatGPT变懒原因:正在给自己放寒假!已被网友测出
ChatGPT近期偷懒严重,有了一种听起来很离谱的解释: 模仿人类,自己给自己放寒假了~ 有测试为证,网友Rob Lynch用GPT-4 turbo API设置了两个系统提示: 一个告诉它现在是5月,另一个告诉它现在是1…...

C#标签设计打印软件开发
1、新建自定义C#控件项目Custom using System; using System.Collections.Generic; using System.Text;namespace CustomControls {public class CommonSettings{/// <summary>/// 把像素换算成毫米/// </summary>/// <param name="Pixel">多少像素…...

Springboot+vue+小程序+基于微信小程序的在线学习平台
一、项目介绍 基于Spring BootVue小程序的在线学习平台从实际情况出发,结合当前年轻人的学习环境喜好来开发。基于Spring BootVue小程序的在线学习平台在语言上使用Java语言进行开发,在数据库存储方面使用的MySQL数据库,开发工具是IDEA。…...

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-13-按键实验
前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…...

ubuntu与redhat的不同之处
华子目录 什么是ubuntu概述 ubuntu版本简介桌面版服务器版 安装部署部署后的设置设置root密码关闭防火墙启用允许root进行ssh登录更改apt源安装所需软件 安装nginx安装apache网络配置Netplan概述配置详解配置文件DHCP静态IP设置设置 软件安装方法apt安装软件作用常用命令配置ap…...

三岁孩童被家养大型犬咬伤 额部撕脱伤达10公分
近期,一名被家养大型犬咬伤了面部的3岁小朋友,在被家人紧急送来西安国际医学中心医院,通过24小时急诊门诊简单救治后,转至整形外科,由主治医师李世龙为他实施了清创及缝合手术。 “患者额部撕脱伤面积约为10公分&…...
@click=“handleClick()“不会传递默认事件参数
当你使用click"handleClick()"这种形式绑定事件处理器时,Vue会将它视为一个函数调用,而不是一个事件监听器。在这种情况下,Vue不会自动传递原生事件对象作为默认参数。 如果你想让Vue自动传递原生事件对象作为默认参数,…...
KVM安装Ubuntu24.04简要坑点以及优点
本机环境是ubuntu22.04的环境,然后是8核16线程 ssd是500的 目前对于虚拟机的选择,感觉kvm确实会更加流畅,最重要的一点是简洁,然后实际安装效果也比较的好,如果对于速度方面希望快一点,并且流畅一点的话这…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...