Spring框架学习-详细
文章目录
- 1. Spring简介
- 1.1 面向接口编程
- 1.2 Spring简介
- 1.3 Spring体系结构
- 2 Spring IoC - 基于XML
- 2.1 Sping框架部署(IoC)
- 2.2 Spring IoC使用
- 2.3 IoC和DI
- 2.4 DI依赖注入
- Spring容器通过反射方法实现属性注入有三种方式
- 1. set方法注入
- 2. 构造器注入
- 2.5 Bean的作用域
- 2.6 bean的声明周期方法
- 2.7 自动装配
- 2.8 Spring IOC 工作原理
- 3 Spring IOC - 基于注解
- 3.1 Spring 框架部署
- 3.2 IoC常用注解
- 1. `@Component`
- 2. `@Scope`
- 3. `@Lazy`
- 4. `@PostConstruct` 与`@PreDestory`
- 5. `@Autowired`
- 6. `@Resource`
- 4 代理设计模式
- 4.1 生活中的代理
- 4.2 静态代理
- 4.3 动态代理
- JDK动态代理实现
- CGLib动态代理实现
- 5 Spring AOP
- 5.1 AOP 的概念
- 5.2 Spring AOP框架部署
- 5.3 AOP配置——基于XML
- 5.4 切入点的声明
1. Spring简介
1.1 面向接口编程
多态:一个父类/接口的引用可以执行其任何一个子类/实现类的对象。
问题: 在Servlet中需要调用Service中的方法,则需要在Servlet类中通过使用new关键字创建Service 的实例对象;在Service实现类中需要调用DAO中的方法,也需要在Service实现类中通过new关键字创建DAO实现类对象。这增加了代码的耦合性、失去了面向接口编程的灵活性。解决方案: 面向接口编程。在Service中定义Service接口的对象变量,不适用new关键字创建实现类对象,在servlet的实例化的时候,通过反射动态的给Service对象变量赋值。
如何实现: Spring可以实现。
1.2 Spring简介
Spring是一个轻量级的控制反转(IoC)和 面向切面(AOP)的容器框架。用途:用来解决企业项目开发的复杂度问题——解耦。
特征:
- 轻量级:体积小,对代码没有侵入性
- 控制反转:IoC(Inverse of Control),把原来该由我们手动new创建对象以及对对象属性赋值(DI,依赖注入)的操作交给了Spring去完成。
- 面向切面:AOP(Aspect Oriented Programming),可以在不改变原有业务逻辑的情况下实现对业务的增强。比如
事务的管理操作
。 - 容器:实例的容器,管理创建的对象。
1.3 Spring体系结构
Spring的生态体系:
Spring Framework:IoC、AOP。核心框架。
Spring Boot:工具框架
Spring Data:Spring提供的数据访问的客户端。(比如访问数据库会用到jpa)
Spring Cloud:微服务架构
Spring Security:安全框架
- Spring的架构图:
Spring中的各个组件学习:
- Core Container:核心容器,是Spring提供的所有功能的基础。Spring的容器组件,用于完成实例的创建和管理。
Beans:对象(实例)管理
Core:
context:容器上下文
SpEL(expression):Spring expression Language,表达式语言。 - AOP、Aspects:Spring的AOP组件,实现面向切面编程
AOP:
Aspects: - web:spring web组件指的是Spring MVC框架(所以Spring MVC其实是Spring的一个组件,只不过我们学习的时候当成一个框架去学习)。用来实现web项目的MVC控制
web:Spring对web项目的支持
webMVC:SpringMVC组件 - Data Acess:Spring数据访问组件,也是一个基于JDBC封装的持久层框架(即使没有MyBatis,Spring也可以完成持久化操作)。
tx:关于事务管理的组件
什么事持久层?
答:可以理解成数据 保存在 数据库或者硬盘一类可以保存很长时间的设备里面,不像放在内存中那样断电就消失了,也就是把数据存在持久化设备上,mybatis就是持久层。
- Test:Spring的单元测试组件们提供了Spring环境下的单元测试支持
test
2 Spring IoC - 基于XML
Spring IOC容器组件,可以完成对象的创建、对象属性赋值、对象管理。
2.1 Sping框架部署(IoC)
步骤如下:
- 创建Maven工程
Spring可以在**Java项目
使用也可以在Web项目
**使用 - 添加Spring IoC依赖
核心的四个(core、beans、expression
、context
(导入context其他四个也会默认导入))+aop
- 创建Spring配置文件
通过配置文件“告诉”Spring容器创建什么对象,给对象属性赋什么值
在resources目录下创建名为applicationContext.xml
的文件名(可自定义)
2.2 Spring IoC使用
使用Spring IoC创建对象并管理对象
步骤如下:
- 创建一个实体类
- 在Spring配置文件中配置实体类
配置文件一般起名为applicationContext.xml
- 初始化Spring对象工厂,获取对象
ClassPathXMLApplicationContext context = new ClassPathXMLApplicationContext("applicationContext.xml");
2.3 IoC和DI
- IoC 控制反转,通过Spring对象工厂完成对象的创建(创建对象)
- DI 依赖注入,在Spring完成对象创建的同时依赖Spring容器完成对象属性的赋值(既创建对象又赋值)
- IoC:当我们需要通过Spring对象工厂创建某个类的对象的时候,需要将这个交给Spring管理——通过bean标签配置
- DI:通过Spring容器给创建的对象属性赋值
2.4 DI依赖注入
Spring容器加载配置文件之后,通过反射创建类的对象,并给属性赋值;
Spring容器通过反射方法实现属性注入有三种方式
- set方法注入
- 构造器注入
- 接口注入(不常用)
1. set方法注入
在bean标签中通过配置property
属性的方式,给属性赋值。(配置property实际上就是通过反射调用set方法给属性赋值,完成属性的注入,所以要求必须得有set方法才行)
(1)简单类型(int、float、double)以及字符串 :直接通过property
标签的value
属性赋值
在这里插入代码片
(2)日期对象 :方式1:在property
标签中通过ref
引用Spring容器中的一个对象;方式2:在property标签中添加字标签bean
来指定对象
在这里插入代码片
(3)自定义类对象属性 :方式1:在property
标签中通过ref
引用Spring容器中的一个对象;方式2:在property标签中添加字标签bean
来指定对象
在这里插入代码片
(4)集合类型 :
a)List:List中的元素是字符串或简单类型的封装,直接赋值;List中的元素使对象类型,则在list标签内加上bean
的子标签,或者加上ref
引用现有容器中的bean
即可
b)Set:与List元素的注入方式相同
c)Map:
<property name="maps"><map><entry><key><value>k1</value></key><value>abc</value></entry><entry><key><value>k2</value></key><value>def</value></entry></map>
</property>
2. 构造器注入
(1)简单类型、字符串类型、对象类型:
(2)集合类型属性:
2.5 Bean的作用域
在bean标签中可以用过scope
属性指定对象的作用域:
scope="singleton"
:表示当前bean
是单例模式。(且默认是饿汉模式,即Spring容器初始化阶段就会完成此对象的创建;当在bean
标签中设置lazy-init="true"
则会变为懒汉模式,什么时候要这个对象什么时候才会创建)每次通过Spring容器获取此bean的对象时都是同一个对象。scope="prototype"
:表示当前bean为非单例模式,即多例模式。每次通过Spring容器获取此bean的对象时都会创建一个新的对象。
2.6 bean的声明周期方法
在bean标签中通过init-method属性指定当前bean的初始化方法,初始化方法在构造器执行之后执行;
通过destroy-method属性指定当前bean的销毁方法,销毁方法在对象销毁之前执行。
具体功能在开发中需要根据具体的业务需求进行操作。
- Bean类
public class Book{private int bookId;private String bookName;//初始化方法:在创建当前类对象时调用的方法,进行一些资源准备的操作public void init(){// 函数内容}//销毁方法:在Spring容器销毁对象时调用此方法,进行一些资源回收性的操作public void destroy(){// 函数内容}
}
- Spring配置文件
<bean id="book" class="com.qfedu.ioc.bean.Book" scope="prototype" init-method="init" destroy-method="destroy">
</bean>
2.7 自动装配
- 自动装配:Spring在实例化当前bean的时候从Spring容器中找到匹配的实例赋值给当前bean的属性
autowire
- 自动装配的策略有两种:
(1)byName
:根据当前Bean的属性名在Spring 容器中寻找匹配的对象,如果根据name找到了bean但是类型不匹配则会抛出异常
(2)byType
:根据当前Bean的属性类型在Spring容器中寻找匹配的对象,如果根据类型找到了多个bean也会抛出异常
2.8 Spring IOC 工作原理
【图】
3 Spring IOC - 基于注解
Spring IOC的使用,需要我们通过XML将类声明给Spring容器进行管理,从而通过Spring工厂完成对象的创建及属性值的注入;
Spring除了提供基于XML的配置方式,同时提供了基于注解的配置:即直接在实体类中添加注解声明给Spring容器管理,以简化开发步骤;
3.1 Spring 框架部署
步骤如下:
- 创建Maven项目
- 添加Spring IOC的依赖:给
pom.xml
配置文件里添加依赖<dependency>
- 创建Spring配置文件:
applicationContext.xml
因为Spring容器初始化时,只会加载applicationContext.xml文件,因此我们在实体类中添加的注解就不会被Spring扫描,所以我们需要在applicationContext.xml声明Spring的扫描范围
,已达到Spring初始化时扫描带有注解的实体类并完成初始化工作
3.2 IoC常用注解
1. @Component
- 类注解,用于声明此类被Spring容器管理,相当于xml中的bean标签作用
@Component(value="stu")
可以通过value属性用于指定当前bean的id,相当于bean标签的id属性,value属性也可省略,若省略则默认当前类的id为类名首字母改小写- 除了@Component之外,@Service、@Controller、@Repository这三个注解也可以将类声明给Spring管理,主要是语义上的区别
@Controller
注解主要声明将控制器类配置给Spring管理,比如Servlet@Service
注解主要声明业务处理类配置Spring管理,Service接口的实现类@Repository
主要声明持久化类配置给Spring管理,比如DAO接口@Component
除了控制器、service和DAO之外的类一律使用此注解声明
2. @Scope
@Scope
注解:用于声明当前类是单例模式还是非单例模式,相当于bean标签的scope属性,默认是单例模式@Scope("prototype")
:声明当前类是非单例模式
3. @Lazy
@Lazy
:类注解,用于声明一个单例模式的Bean是否为懒汉模式,默认为true懒汉模式@Lazy(false)
:声明当前类是恶汉模式
4. @PostConstruct
与@PreDestory
@PostConstruct
:方法注解,声明一个方法为当前类的初始化方法(在构造器之后执行),相当于bean标签的init-method
属性@PreDestory
:方法注解,声明一个方法为当前类的销毁方法(在对象从容器中释放之前执行),相当于bean标签的destory-method
属性
5. @Autowired
- 属性注解、方法朱姐(set方法),声明当前属性自动装配,默认根据类型匹配byType,默认如果没有找到类型与属性匹配的bean则抛出异常(required=true)
@Autowired(required=false)
通过required
属性配置当前自动装配的对象是否是必须的,false
就表示非必须@Qualifier("clazz")
:放到参数的set方法的参数引用括号里,表明其属性的set是按照这个名字去取的
@Autowired
public void setClazz(@Qualifier("c2") Clazz clazz){this.clazz = clazz;
}
6. @Resource
- 属性注解,也用于默认属性自动装配
- 默认装配方式byName;若根据byName没有找到对应的bean,则继续根据byType寻找对应的bean,根据byType如果没有找到bean或找到不止一个类型的bean,则抛出异常
4 代理设计模式
4.1 生活中的代理
代理设计模式的优点:将通用性的工作都交给代理对象完成,被代理对象只需专注自己的核心业务
4.2 静态代理
- 静态代理: 代理类只能为特定的类生产代理对象,不能代理任意类
- 使用代理的好处:
(1)被代理类中只用关注核心业务的实现,将通用的管理型逻辑(事务管理、日志管理)和业务逻辑分离
(2)将通用的代码(事务管理、日志管理等)放在代理类中实现,提供了代码的复用性
(3)通过在代理类添加业务逻辑,实现对原有业务逻辑的扩展(增强)
4.3 动态代理
- 动态代理: 几乎可以为所有的类产生代理对象
- 动态代理的实现方式有2种:
- JDK动态代理
- CGLib动态代理
JDK动态代理实现
- JDK动态代理,是通过被代理对象实现的接口产生其代理对象的:
- 创建一个类,实现InvocationHandler接口,重写invoke方法
- 在类中定义一个Object类型的变量,并提供这个变量的有参构造器,用于将被代理对象传递进来
- 定义getProxy方法,用于创建并返回代理对象
CGLib动态代理实现
- 由于JDK动态代理是通过被代理类实现的接口来创建代理对象的,因此JDK动态代理只能代理实现了接口的类的对象。如果一个类没有实现任何接口,该如何产生代理对象呢?
- CGLib动态代理,是通过创建被代理类的子类来创建代理对象的,因此即使没有实现任何接口的类也可以通过CGLib产生代理对象
- CGLib动态代理不能为final类创建代理对象
- 添加cglib的依赖
<!-- https://mvnrepository.com/artifact/cglib/cglib --> <dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>3.3.0</version> </dependency>
- 创建一个类,实现
MethodInterceptor
接口,同时实现接口中的intercept
方法- 在类中定义一个Object类型的变量,并提供这个变量的有参构造器,用于传递被代理对象
- 定义
getProxy
方法创建并返回代理对象(代理对象是通过创建被代理类的自雷来创建的)
5 Spring AOP
5.1 AOP 的概念
Aspect Oriented Programming 面向切面编程,是一种利用“横切”的技术(底层实现就是动态代理),对原有的业务逻辑进行拦截,并且可以再这个拦截的横切面上添加特定的业务逻辑,对原有的业务进行增强。
基于动态代理实现在不改变原有业务的情况下对业务逻辑进行增强。
连接点:程序中的所有方法都是连接点
切入点:被Spring横切的方法
切点:添加到切入点的新增的业务方法
切面:就是定义切点方法的类
通过配置来告诉Spring AOP需要将切点放到切入点的位置
5.2 Spring AOP框架部署
- 创建Maven项目
- 添加依赖:context、aspects
- 创建配置Spring配置文件
- 需要引入aop的命名空间
5.3 AOP配置——基于XML
在DAO的方法添加开启事务和提交事务的逻辑
AOP开发步骤:
- 创建一个切面类,定义要添加的业务逻辑,在切面类定义切点方法
- 在配置文件applicationContext.xml中配置aop,将切面类配置给Spring容器
(1)声明切入点
(2)声明切面类 - 配置AOP的通知策略
5.4 切入点的声明
注意:
如果要使用Spring aop面向切面编程,调用切入点的方法的对象必须通过Spring容器获取;
如果一个类中的方法被声明为切入点并且织入了切入点之后,通过Spring容器获取该类对象,实则获取到的是一个代理对象;
如果一个类中的方法没有被声明为切入点,通过Spring容器获取的就是这个类真实创建的对象
各种切入点的声明方式:
(待更新)
AOP使用注意事项:
(待更新)
相关文章:

Spring框架学习-详细
文章目录 1. Spring简介1.1 面向接口编程1.2 Spring简介1.3 Spring体系结构 2 Spring IoC - 基于XML2.1 Sping框架部署(IoC)2.2 Spring IoC使用2.3 IoC和DI2.4 DI依赖注入Spring容器通过反射方法实现属性注入有三种方式1. set方法注入2. 构造器注入 2.5 …...

fatal: fetch-pack: invalid index-pack output
解决方案:git clone --depth1 要克隆的git地址 下载最近一次提交的代码 其他分支的内容都不下载 这样整体下载体量就变小了 执行命令:git clone --depth 1 https://gitlab.scm321.com/ufx/xxxx.git...
相机购买指南
佳能1000D 上市时间:2008年6月 简介: 佳能1000D具有1010万有效像素和7点宽区域自动对焦系统。DIGIC III影像处理器的应用使高ISO画质得到提升。小巧的机身和优质的成像质量可以满足初级用户对旅游便携与高画质的要求。使用了DIGIC III影像处理器&#x…...

STM32微秒级别延时--F407--TIM1
基本配置: TIM1挂载在APB2总线上,150MHz经过15分频,得到10MHz计数频率,由于disable了自动重装载,所以只需要看下一次计数值是多少即可。 void TIM1_Delay_us(uint16_t us) //使用阻塞方式进行延时,ARR值不…...

AI图书推荐:杀手级ChatGPT提示词——利用人工智能实现成功与盈利
《杀手级ChatGPT提示词——利用人工智能实现成功与盈利》(Killer ChatGPT Prompts_ Harness the Power of AI for Success and Profit )一书是作者Guy Hart-Davis关于ChatGPT的指南,ChatGPT是OpenAI开发的大语言模型。这本书提供了各种职业角…...
AI时代:低代码与人工智能引领科技创造新时代
随着科技的飞速发展,我们步入了一个崭新的时代——AI时代。在这个时代,低代码和人工智能技术如日中天,成为引领科技创造的新引擎。本文将围绕这一主题,探讨低代码和人工智能如何在各个领域发挥巨大作用,推动科技创造迈…...

1.基于python的单细胞数据预处理-降维可视化
目录 降维的背景PCAt-sneUMAP检查质量控制中的指标 参考: [1] https://github.com/Starlitnightly/single_cell_tutorial [2] https://github.com/theislab/single-cell-best-practices 降维的背景 虽然特征选择已经减少了维数,但为了可视化࿰…...

【快捷部署】023_HBase(2.3.6)
📣【快捷部署系列】023期信息 编号选型版本操作系统部署形式部署模式复检时间023HBase2.3.6Ubuntu 20.04tar包单机2024-05-07 注意:本脚本非全自动化脚本,有2次人工干预,第一次是确认内网IP,如正确直接回车即可&#…...
Nginx配置项详解
Nginx,以其高性能、稳定性强、资源消耗低的特性,成为众多网站和应用首选的Web服务器及反向代理服务器。其配置文件的灵活性和丰富性是其强大功能的关键所在。本文将深入解析Nginx配置文件中的核心概念与关键配置项,帮助您更好地理解和定制Ngi…...

解决iview(view ui)中tabs组件中使用图片预览组件ImagePreview,图片不显示问题
同学们可以私信我加入学习群! 正文开始 前言一、问题描述二、原因分析三、解决方案总结 前言 最近在写个人项目的web端和浏览器插件,其中一个功能是base64和图片的转换。因为分成四个小功能,所以使用的iview的tabs来展示不同功能,…...

R2S+ZeroTier+Trilium
软路由使用ZeroTier搭建远程笔记 软路由使用ZeroTier搭建远程笔记 环境部署 安装ZeroTier安装trilium 环境 软路由硬件:友善 Nanopo R2S软路由系统:OpenWrt,使用第三方固件nanopi-openwrt。内网穿透:ZeroTier。远程笔记&…...

10 华三vlan技术介绍
AI 解析 -Kimi-ai Kimi.ai - 帮你看更大的世界 (moonshot.cn) 虚拟局域网(VLAN)技术是一种在物理网络基础上创建多个逻辑网络的技术。它允许网络管理员将一个物理网络分割成多个虚拟的局域网,这些局域网在逻辑上是隔离的,但实际…...
实现一个聊天室可发送消息语音图片视频表情包(任意文件)
文章目录 如何跑通代码仓库地址客户端登录发送消息接受消息发送文件接受文件 服务端接受消息并发送给各个客户端接受文件并发送给各个客户端 如何跑通 将手机和电脑都连自己的热点先运行服务器得到可监听的地址更新客户端安卓消息线程和文件线程的socker目标地址为可监听地址然…...

【SpringMVC 】什么是SpringMVC(一)?如何创建一个简单的springMvc应用?
文章目录 SpringMVC第一章1、什么是SpringMVC2、创建第一个SpringMVC的应用1-3步第4步第5步第6步7-8步3、基本语法1、进入控制器类的方式方式1:方式2:方式3:方式4:方式5:2、在控制器类中取值的方式方式1:方式2:方式3:方式4:方式5:方式6:超链接方式7:日期方式8:aja…...

【配置】IT-Tools部署
github地址 docker运行如下,记得打开云服务器的9090端口 docker run -d --name it-tools --restart unless-stopped -p 9090:80 corentinth/it-tools:latestip:9090查看,很香大部分工具都有...
【Python】如何训练模型并保存本地和加载模型
这个年纪的我们 爱情跟不上分开的节奏 这个年纪的我们 更珍惜难得的自由 这个年纪的我们 比起从前更容易感动 这个年纪的我们 徘徊在理想与现实之中 🎵 齐一《这个年纪》 逻辑回归是一种常用的分类算法,能够根据输入特征预测目标变…...

浅谈如何利用 AI 提高内容生产效率?|TodayAI
在数字化时代,内容的创建和分发速度变得尤为关键。人工智能(AI)技术提供了加速这一过程的可能性,不仅提升了生产效率,还改善了内容的质量和受众的接受度。本文深入探讨AI如何在内容生成、分发与推广,以及内…...

毕业论文答辩PPT怎么做?推荐3个ai工具帮你一键生成答辩ppt
在我原本的认知里面,答辩PPT是要包含论文各个章节的,在答辩时需要方方面面都讲到的,什么摘要、文献综述、实证分析、研究结果样样不落。但是,这大错特错! 答辩PPT环节时长一般不超过5分钟,老师想要的答辩P…...

力扣 5-11
704. 二分查找 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 这道题目的前提是数组为有序数组,同时题目还强…...
redisson 使用脚本实现判断元素不在队列中则插入的原子操作
脚本逻辑: 取出队列所有元素遍历元素查找值是否存在不存在则推入 final String scriptText """local valuesInTarget redis.call(lrange, KEYS[1], 0, -1);local index 0;for i, v in ipairs(valuesInTarget) doif v value thenindex ibreake…...
基于ROS2,撰写python脚本,根据给定的舵-桨动力学模型实现动力学更新
提问 #! /usr/bin/env python3from control_planner import usvParam as P from control_planner.courseController import courseLimitationimport tf_transformations # ROS2没有自带tf.transformations, 需装第三方库 import rclpy from rclpy.node import Node from pid_…...
【判断既约分数】2022-4-3
缘由既约分数,除了辗转相除法-编程语言-CSDN问答 void 判断既约分数() {int a 1, b 2020, aa b, y 2, gs 0;while (aa){while (a < b){while (y < a && y < aa)if (a%y 0 && aa%y 0)a, y 2;elsey;if (a < b)gs; else;a, y 2;…...
STM32学习之I2C(理论篇)
📢:如果你也对机器人、人工智能感兴趣,看来我们志同道合✨ 📢:不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍…...

从 Revit 到 3DTiles:GISBox RVT 切片器如何让建筑图元在 Web 端展示
在GIS(地理信息系统)行业蓬勃发展的当下,数据处理与展示的效率和精准度成为关键。GISBox作为一款功能强大的一站式三维GIS数据编辑、转换、发布平台,凭借其独特的“RVT切片器”功能,在RVT图元处理方面也有着不俗的表现…...
OkHttp 3.0源码解析:从设计理念到核心实现
本文通过深入分析OkHttp 3.0源码,揭示其高效HTTP客户端的实现奥秘,包含核心设计理念、关键组件解析、完整工作流程及实用技巧。 一、引言:为什么选择OkHttp? 在Android和Java生态中,OkHttp已成为HTTP客户端的标准选择…...

最新Spring Security实战教程(十七)企业级安全方案设计 - 多因素认证(MFA)实现
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》…...

全生命周期的智慧城市管理
前言 全生命周期的智慧城市管理。未来,城市将在 实现从基础设施建设、日常运营到数据管理的 全生命周期统筹。这将避免过去智慧城市建设 中出现的“碎片化”问题,实现资源的高效配 置和项目的协调发展。城市管理者将运用先进 的信息技术,如物…...

思尔芯携手Andes晶心科技,加速先进RISC-V 芯片开发
在RISC-V生态快速发展和应用场景不断拓展的背景下,芯片设计正面临前所未有的复杂度挑战。近日,RISC-V处理器核领先厂商Andes晶心科技与思尔芯(S2C)达成重要合作,其双核单集群AX45MPV处理器已在思尔芯最新一代原型验证系…...

如何使用Webhook触发器,在 ONLYOFFICE 协作空间构建智能工作流
在数字化办公中,ONLYOFFICE 协作空间作为一款功能强大的文档协作平台,提供了丰富的自动化功能。对于开发者而言,Webhook 触发器是实现业务流程自动化与系统集成的关键工具。本文将深入探讨如何在 ONLYOFFICE 协作空间中高效利用 Webhook&…...

html-pre标签
我们都知道在常见标签里面的文字的格式是不会显示的,比如你打了多个空格,但却不会显示,而pre标签会显示。 主要特点: 保留空格和换行:在 <pre> 标签内,HTML 会保留所有的空格、换行符和制表符等格式…...