React面向组件编程(定义组件,组件三大核心属性,组件事件处理、组件收集表单数据、高阶函数和函数的柯里化)

news2024/9/21 21:59:18

目录

一、React中定义组件

1、函数式组件

2、类式组件

二、组件三大核心属性

1、组件三大核心属性1: State(状态)

2、组件三大核心属性2: props

3、组件三大核心属性3: ref

 三、组件事件处理

1、事件处理

 四、组件收集表单数据

1、受控组件

2、非受控组件

 五、高阶函数和函数的柯里化

1、高阶函数柯里化

2、不用柯里化实现


一、React中定义组件

1、函数式组件

(1)实质:一个 React 应用就是构建在 React 组件之上的。

(2)函数组件:该函数是一个有效的 React 组件,因为它接收唯一带有数据的 “​props​”(代表属性)对象与并返回一个 React 元素。这类组件被称为“函数组件”,因为它本质上就是 JavaScript 函数。

(3)代码展示如下

<!-- 准备好一个“容器” -->
	<div id="test"></div>
	
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel">
		//1.创建函数式组件
		function MyComponent(){
			console.log(this); //此处的this是undefined,因为babel编译后开启了严格模式
			return <h2>我是用函数定义的组件(适用于【简单组件】的定义)</h2>
		}
		//2.渲染组件到页面
		ReactDOM.render(<MyComponent/>,document.getElementById('test'))
	</script>

(4)注意:

    1.组件名必须首字母大写

    2.虚拟DOM元素只能有一个根元素

    3.虚拟DOM元素必须有结束标签

    4.函数名就是组件名

2、类式组件

(1)含义:

ES6 的 class 来定义组件,通过继承React.Component。解析流程如下:

React解析组件标签,找到了MyComponent组件。

发现组件是使用类定义的,随后new出来该类的实例,并通过该实例调用到原型上的render方法。将render返回的虚拟DOM转为真实DOM,随后呈现在页面中。

(2)代码展示

<!-- 准备好一个“容器” -->
	<div id="test"></div>
	<!-- 引入react核心库 -->
	<script type="text/javascript" src="../js/react.development.js"></script>
	<!-- 引入react-dom,用于支持react操作DOM -->
	<script type="text/javascript" src="../js/react-dom.development.js"></script>
	<!-- 引入babel,用于将jsx转为js -->
	<script type="text/javascript" src="../js/babel.min.js"></script>

	<script type="text/babel">
		class MyComponent extends React.Component {
			render(){
				return <h2>我是用类定义的组件(适用于[复杂组件]的定义)</h2>
			}
		}
		//2.渲染组件到页面
		ReactDOM.render(<MyComponent/>,document.getElementById('test'))
	</script>

(3)注意:

    1.组件名必须首字母大写

    2.虚拟DOM元素只能有一个根元素

    3.虚拟DOM元素必须有结束标签

    4.类名就是组件名

二、组件三大核心属性

1、组件三大核心属性1: State(状态)

1.1什么是state

state是组件对象最重要的属性,值是对象(可以包含多个key:value的组合),组件被称为`状态机`,通过更新组件的state来更新对应的页面显示(重新渲染组件),有state称为复杂组件。

1.2 State的用法

State 的使用对象形式(key,value);

代码演示:

 <div id="root"></div>
    <script src="../react.development.js"></script>
    <script src="../react-dom.development.js"></script>
    <script src="../babel.min.js"></script>
    <script type="text/babel">
        class Flag extends React.Component{
            state={
                isflag : false,
            }
            changeFlag=()=>{
                let {isflag,count}= this.state;
                this.setState({isflag:!isflag,count:++count})
                console.log(this.state.isflag);
            }
    
            render() {
                let {isflag,count}= this.state;
                return (
                  <div>
                    <button className={isflag?"yes":"no"}>
                    {isflag?"已关注":"未关注"}                            
                    </button>
                  </div>
                )
            }
        }
        ReactDOM.render(<Flag/>,document.getElementById('root'))
    </script>

这里呢我们只能通过控制台来实现我们想要的已关注和未关注的效果,下面我们来讲一下react绑定事件

 1.3react 绑定事件

在react应用中,事件名都是用小驼峰格式进行书写,例如onclick要改写成onClick

 <button className={isflag?"yes":"no"}onClick={this.changeFlag}>
    {isflag?"已关注":"未关注"}
</button>

                注意:

                1、onclick 变为 onClick。

                2、{函数名}返回值给click,加()就会直接调用。

2、组件三大核心属性2: props

        2.1 基础用法

· 每个组件对象都会有props(properties的简写)属性。

· 组件标签的所有属性都保存在props中。

· props 是不可变的,只能通过 props 来传递数据。

        2.2代码展示:

(1)基础用法

<body>
     <!-- 引入react核心库 -->
     <div id="root"></div>
     <!-- 引入react核心库 -->
     <script src="../react.development.js"></script>
     <!-- 引入react-dom,用于支持react操作DOM -->
     <script src="../react-dom.development.js"></script>
     <!-- 引入babel,用于将jsx转为js -->
     <script src="../babel.min.js"></script>
    <script type="text/babel">
        class Person extends React.Component {
            render() {
                let {realname,age} = this.props //props接收参数
                return  (
                    <div>
                        <p>姓名:{realname}</p>
                        <p>年龄:{age}</p>
                    </div>
                ) 
            }

        }
        ReactDOM.render(<Person realname="张三" age={19}/>,document.getElementById("root"))
    </script>
</body>

(2)批量传参

<body>
    <!-- 引入react核心库 -->
    <div id="root"></div>
    <!-- 引入react核心库 -->
    <script src="../react.development.js"></script>
    <!-- 引入react-dom,用于支持react操作DOM -->
    <script src="../react-dom.development.js"></script>
    <!-- 引入babel,用于将jsx转为js -->
    <script src="../babel.min.js"></script>
    <!-- props验证 -->
    <script src="../prop-types.js"></script>
    <script type="text/babel">
        class Person extends React.Component {
            render() {
                let {realname,age} = this.props //props接收参数
                return  (
                    <div>
                        <p>姓名:{realname}</p>
                        <p>年龄:{age}</p>
                    </div>
                ) 
            }
        }
        const p1 = {realname:"张三",age:19} 
         //批量传参
        ReactDOM.render(<Person {...p1}/>,document.getElementById("root"))
    </script>
</body

(3)参数限制

使用prop-types库进限制(需要引入prop-types库)

<!-- 引入prop-types,用于对组件标签属性进行限制 -->
<script type="text/javascript" src="../js/prop-types.js"></script>

	<!-- 引入prop-types,用于对组件标签属性进行限制 -->
	<script type="text/javascript" src="../js/prop-types.js"></script>
		//对标签属性进行类型、必要性的限制
		Person.propTypes = {
			name:PropTypes.string.isRequired, //限制name必传,且为字符串
			sex:PropTypes.string,//限制sex为字符串
			age:PropTypes.number,//限制age为数值
			speak:PropTypes.func,//限制speak为函数
		}
		//指定默认标签属性值
		Person.defaultProps = {
			sex:'男',//sex默认值为男
			age:18 //age默认值为18
		}
	</script>

3、组件三大核心属性3: ref

定义:组件内的标签可以定义ref来标识自己。

我们做一个小案例来认识一下,我们需要两个input框,中间有个button按钮,点击button按钮,提示左边输入框内的信息,右边input框我们是失去焦点获得信息

如下图:

(1)字符串形式的ref(不推荐使用

<script type="text/babel">
		//创建组件
		 class Demo extends React.Component{
			//  展示左侧输入框的数据
			showData = ()=>{
				const {input1} = this.refs
				alert(input1.value);
			}
				//  展示右侧输入框的数据
			showData2 =()=>{
				const {input2} = this.refs
				alert(input2.value);
			}
			 render() {
				return (
					<div>
						<input ref="input1" type="text" name="" placeholder="点击按钮提示数据" />&nbsp;&nbsp;&nbsp;
						<button  onClick={this.showData}>点我提示左侧的数据</button>&nbsp;&nbsp;&nbsp;
						<input ref="input2" onBlur={this.showData2} type="text" name="" placeholder="失去焦点提示数据"/>
					</div>
				)	 
			 }
		 }
		 ReactDOM.render(<Demo/>,document.getElementById('root'))
	</script>

写法就是ref后面加的是内容时引号套起来的内容

 这种方法在React的官网中一说说明了,不推荐使用,后面可能会淘汰掉,所以我们看看其他的方法

(2)回调函数的ref

<script type="text/babel">
		//创建组件
		class Demo extends React.Component{
			//展示左侧输入框的数据
			showData = ()=>{
				const {input1} = this
				alert(input1.value)
			}
			//展示右侧输入框的数据
			showData2 = ()=>{
				const {input2} = this
				alert(input2.value)
			}
			render(){
				return(
					<div>
						<input ref={c => this.input1 = c } type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} ref={c => this.input2 = c } type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
	</script>

写法就是ref后面加的是内容时大括号套起来的函数,采用的是先赋值在回调函数

 (3)createRef(目前React最推荐的方式)

<script type="text/babel">
		//创建组件
		class Demo extends React.Component{
			myRef = React.createRef()
			myRef2 = React.createRef()
			//展示左侧输入框的数据
			showData = (e)=>{
				console.log(this.myRef);
				console.log(this.myRef.current);
                console.log(this.myRef.current.value);
				alert(this.myRef.current.value);
			}
			//展示右侧输入框的数据
			showData2 = ()=>{
				alert(this.myRef2.current.value);
			}
			render(){
				return(
					<div>
						<input ref={this.myRef} type="text" placeholder="点击按钮提示数据"/>&nbsp;
						<button onClick={this.showData}>点我提示左侧的数据</button>&nbsp;
						<input onBlur={this.showData2} ref={this.myRef2} type="text" placeholder="失去焦点提示数据"/>&nbsp;
					</div>
				)
			}
		}
		//渲染组件到页面
		ReactDOM.render(<Demo a="1" b="2"/>,document.getElementById('test'))
	</script>

关于createRef我们需要把重点关注在这三个地方

就是创建了一个容器,这个容器挂载了实例的自身上,起了个名字叫myRef或者myRef2

这句话的意思就是因为写了ref ,写的是用createRef创建的容器,就把当前ref所在的节点储存到这个节点中(切记不是回调函数)

 这是第三个重点,我在代码中打印了这三个,那这三个分别是什么意思呢

第一个:打印出来的就是ref给我们创建的节点

第二个:打印出来的就是我们放到节点中的input

第三个:打印出来才是我们想要的结果,curren不能少

 三、组件事件处理

1、事件处理

1. 通过onXxx属性指定事件处理函数(οnclick===>onClick)

       1)为了更好的兼容性:React使用的是自定义(合成事件,而不是使用的原生DOM事件)

       2)为了更高效:React中的事件是通过事件委托的方式处理的(委托给组件最外层的元素)

2.当发生事件的事件源与操作源相同时,通过event.target得到发生事件的DOM元素对象。

发生事件源的要操作自身属性的时候 不要用ref

 四、组件收集表单数据

说的收集表单数据我们就要聊到react中的组件,组件分为将状态变化交由React处理的组件和通过ref引用获取的组件两种,前者称为受控组件,后者称为非受控组件,非受控组件的状态在组件自身存储,需要的时候通过ref查询DOM并查找其值。

1、受控组件

(1)受控组件通过props获取其当前值,并通过回调函数(比如onChange)通知变化表单状态发生变化时,都会通知React,将状态交给React进行处理,比如可以使用useState存储

(2)受控组件中,组件渲染出的状态与它的valuechecked属性相对应

(3)受控组件会更新state的流程

<script type="text/babel">
		//创建组件
		class Login extends React.Component{
			state={
				username:"", //用户名
				password:"", // 密码
			}
			saveUsername=(event)=>{
				this.setState({username:event.target.value}) 
			}
			savePassword = (event) =>{
				this.setState({password:event.target.value})
			}
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交
				const {username,password} = this.state 
				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
			}
			render(){
				return(
					<form onSubmit={this.handleSubmit}>
						用户名:<input onChange={this.saveUsername} type="text" name="username"/>
						密码:<input onChange={this.savePassword} type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}
		}
		ReactDOM.render(<Login/>,document.getElementById('test'))
	</script>

代码解析:

代码中有两个输入框,一个的登录框,点击登录展示了输入框的内容,在控制台可以看打随着输入框内容的变化,上方文字相应变化。表单组件Input的值通过onChange回调交给React处理React获取到表单的值(e.target.value)之后,将其保存到了状态变量usernamepassword中界面展示内容通过读取组件状态userename和password,因此userename和password的变化触发组件的重新渲染

2、非受控组件

非受控组件将数据存储在DOM中,而不是组件内,这比较类似于传统的HTML表单元素。

  1. 非受控组件的值不受组件自身的stateprops控制
  2. 非受控组件使用refDOM中获取元素数据
<script type="text/babel">
		//创建组件
		 class Login extends React.Component{
			handleSubmit=(event)=>{
				event.preventDefault(); //阻止表单默认提交
				const {username,password} = this
				alert(`你输入的用户名是:${username.value},你输入的密码是:${password.value}`)
			}
			 render() {
				 return(
					 <div>
						<form action="http://www.baidu.com" onSubmit={this.handleSubmit}>
							用户名:<input  ref={c => this.username = c} type="text" name="username"/>
							密码:<input ref={c => this.password =c} type="password" name="password"/>
							<button>登录</button>
						</form>
					 </div>
				 )
			 }
		 }
		//渲染组件
		ReactDOM.render(<Login/>,document.getElementById("test"))
	</script>

代码中有两个输入框,一个的登录框,点击登录展示了输入框的内容,随着输入框内容的变化,上方文字相应变化。

React通过ref获取input元素的值

input值由用户改变,点击提交按钮,在handleSubmit中通过ref获取DOM元素,进而读取输入框的值

输入框的变化并未交由组件控制,而是通过ref获取,也就是直接在DOM中读取

 五、高阶函数和函数的柯里化

1、高阶函数柯里化

定义:如果一个函数符合下面两个规范中的任何一个,那该函数就是高阶函数

·若A函数,接受的参数是一个函数,那么A就可以称之为高阶函数

·若A函数,调用的返回值依然是一个函数,那么A就可以称之为高阶函数

常见的高阶函数有:Promise、setTimeout()、arr.map()等等

说了一大推定义,可能还是看不懂,所以下面直接看代码,在开发的过程总会遇到一种事情,而且很多次。我们来看一下我们上面收集表单数据的写法

 可以看到我们上面的onChange事件写了两次,一次是为用户名的,一次是为密码的。现在还好只有两个,但是我们要是有10个呢?难道我们就要写10次onChange?光是想命名就很难受了,所以我们就有了下面的这两种方法

<script type="text/babel">
		//创建组件
		class Login extends React.Component{
			//初始化状态
			state = {
				username:'', //用户名
				password:'' //密码
			}
			//保存表单数据到状态中
			saveFormData = (dataType)=>{
				console.log(dataType);
				return (event)=>{
					this.setState({[dataType]:event.target.value})
				}
			}
			//表单提交的回调
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交
				const {username,password} = this.state
				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
			}
			render(){
				return(
					<form onSubmit={this.handleSubmit}>
						用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
						密码:<input onChange={this.saveFormData('password')} type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}
		}
		//渲染组件
		ReactDOM.render(<Login/>,document.getElementById('test'))
	</script>

这里我们看onChange事件就写一次就可以完成了,是不是方便很多呢。这里saveFormData的返回值依然是个函数,这个函数才是真正onChange的回调。

有人说我不会高阶函数柯里化的写法,有没有别的,当然有的。

2、不用柯里化实现

<script type="text/babel">
		class Login extends React.Component{
			//初始化状态
			state = {
				username:'', //用户名
				password:'' //密码
			}

			//保存表单数据到状态中
			saveFormData = (dataType,event)=>{
				this.setState({[dataType]:event.target.value})
			}
			//表单提交的回调
			handleSubmit = (event)=>{
				event.preventDefault() //阻止表单提交
				const {username,password} = this.state
				alert(`你输入的用户名是:${username},你输入的密码是:${password}`)
			}
			render(){
				return(
					<form onSubmit={this.handleSubmit}>
						用户名:<input onChange={(event)=>{this.saveFormData('username',event)}} type="text" name="username"/>
						密码:<input onChange={event => this.saveFormData('password',event) } type="password" name="password"/>
						<button>登录</button>
					</form>
				)
			}
		}
		//渲染组件
		ReactDOM.render(<Login/>,document.getElementById('test'))

这种就是常规的写法,写个回调然后里面有个函数,通过传入类型和值,去修改相应的state,这个也还是个高阶函数,但是没有了柯里化了。

本篇的内容就到此结束了,本篇篇幅较长,也希望能帮到给为看官们,写的也不是特别详细。希望看官们能留个赞再走哇。最后用一句话结束本篇

                                                                                        ——十年后所有的难过都是下酒菜

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【数据结构】算法的时间复杂度和空间复杂度

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f40c; 个人主页&#xff1a;蜗牛牛啊 &#x1f525; 系列专栏&#xff1a;&#x1f6f9;初出茅庐C语言、&#x1f6f4;数据结构 ☀️ 学习格言&#xff1a;眼泪终究流不…

象棋中的马跳步问题

象棋中的马跳步问题 作者&#xff1a;Grey 原文地址&#xff1a; 博客园&#xff1a;象棋中的马跳步问题 CSDN&#xff1a;象棋中的马跳步问题 题目描述 中国象棋中&#xff0c;整个棋盘就是横坐标上 9 条线、纵坐标上 10 条线的一个区域&#xff0c;给你三个 参数 x&…

计算机毕业设计springboot+vue基本微信小程序的汽车租赁公司小程序

项目介绍 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的管理系统应运而生&#xff0c;各行各业相继进入信息管理时…

【Vue】环境搭建

Vue 简介&#xff1a; 一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与第三方库或既有项目整合。另一方面&#xff0c;当与现代化的工具链以…

Jenkins+Docker 一键自动化部署 SpringBoot 项目

本文章实现最简单全面的 Jenkins Docker Spring Boot 一键自动部署项目。步骤齐全&#xff0c;少走坑路。 环境&#xff1a;CentOS7 Git (Gitee) 实现步骤&#xff1a;在 Docker 安装 Jenkins&#xff0c;配置 Jenkins 基本信息&#xff0c;利用 Dockerfile 和 Shell 脚本实…

CSS 的布局 盒子

目录 块级元素和行内元素 块级元素 特点&#xff1a; 行内元素 特点&#xff1a; 行内元素 和 块级元素 的区别 改变显示模式&#xff08;把行内元素 变成 块级元素) 盒模型 盒模型图 边框基础属性 内边框、外边框 基础写法&#xff1a; 复合写法 块级元素水平居中 前提&#…

C++知识点大全(第二版)

目录 1 C简介 1.1 起源 1.2 应用范围 1.3 C和C 2开发工具 3 基本语法 3.1 注释 3.2关键字 3.3标识符 4 数据类型 4.1基本数据类型 4.2 数据类型在不同系统中所占空间大小 4.3 typedef声明 4.4 枚举类型 5 变量 5.1 变量的声明和定义 5.2 变量的作用域 6 运算…

如何当好硬软件助理工程师——实习周报(一)

如何当好硬软件助理工程师——实习周报 如何当好硬软件助理工程师——实习周报&#xff08;一&#xff09; 文章目录如何当好硬软件助理工程师——实习周报前言一、问题积累1.git 指令2.Coding的使用3.代码中的知识点&#xff08;HAL库、Flash读写&#xff09;a.gpio配置b.fla…

程序员必备的画图工具汇总

文章目录1、简介2、draw.io3、Excalidraw4、Xmind5、语雀6、Database6.1 dbdiagram.io6.2 sqldbm6.3 QuickDBD7、UML7.1 plantuml7.2 Graphviz结语1、简介 优秀的作图工具有许多&#xff0c;例如文本绘图工具 PlantUML&#xff0c;流程图设计工具 Draw.io&#xff0c;还有专业…

ORA-01861: literal does not match format string

系统&#xff1a;AnolisOS7.9 数据库&#xff1a;Oracle11.2.0.4 问题描述&#xff1a;执行TSPITR时&#xff0c;报错ORA-01861&#xff0c;如下所示&#xff1a; [oracleliujun~]$ export NLS_DATE_FORMATyyyy-mm-dd hh24:mi:ss [oracleliujun~]$ export NLS_LANGAMERICAN…

手写Mybatis源码(原来真的很简单!!!)

目录一、JDBC操作数据库_问题分析二、自定义持久层框架_思路分析三、自定义框架_编码1、加载配置文件2、创建两个配置类对象3、解析配置文件&#xff0c;填充配置类对象4、创建SqlSessionFactory工厂接口及DefaultSqlSessionFactory实现类5、创建SqlSession会话接口及DefaultSq…

R语言和医学统计学(10):正态性和方差齐性检验

本文首发于公众号&#xff1a;医学和生信笔记&#xff0c;完美观看体验请至公众号查看本文。 医学和生信笔记&#xff0c;专注R语言在临床医学中的使用&#xff0c;R语言数据分析和可视化。 文章目录前言正态性检验shapiro wilk检验kolmogorov smimov检验方差齐性检验两样本方差…

SSH框架重构需求,起码读懂代码和前端的原生JS

文章目录SSH(Spring Struts Hibernate)商城老项目JSPHtmlJsJquery 老项目部署Tomcat上面进行部署可以一次性部署多个项目1.Spring2.Struts3.Hibernate(持久层一个重量级框架)4.里面的请求路径解析SSH(Spring Struts Hibernate)商城老项目JSPHtmlJsJquery 老项目部署 Tomca…

【JavaSE之JDK8新特性】三万字详文带你了解JDK8新特性

JDK8新特性一、Lambda1.1需求分析2.Lambda表达式的初级体验3.Lambda表达式的语法规则3.1.Lambda练习13.2.Lambda表达式练习24.FunctionalInterfa注解说明5.Lambda表达式的原理6.Lambda表达式的省略写法7.lambda表达式的使用前提8.lambda和匿名内部类的对比二、接口中新增的方法…

#define宏的妙用!实现你以为的函数offsetof等

目录 一.#define 1.1#define的使用 1.2在define定义标识符的时候&#xff0c;要不要在最后加上 ;? 二.#define定义宏 2.1好代码的写法: 2.2#define 替换规则 2.3#和## 三.带有副作用的宏参数 四.宏和函数的对比 五.实现offetof 思路解析过程&#xff1a; 代码实现&am…

破解系统密码

一、利用5次shift漏洞破解win7密码 1.1 漏洞 1. 在未登录时&#xff0c;连续按5次shift键&#xff0c;弹出程序C:\Windows\System32\sethc.exe 2. 部分win7及win10系统在未进入系统时&#xff0c;可以通过系统修复漏洞篡改系统文件名&#xff01; 注意&#xff1a;如win7或win…

SpringBoot/Spring AOP默认动态代理方式

Spring 5.x中AOP默认依旧使用JDK动态代理SpringBoot 2.x开始&#xff0c;AOP为了解决使用JDK动态代理可能导致的类型转换异常&#xff0c;而使用CGLIB。在SpringBoot 2.x中&#xff0c;AOP如果需要替换使用JDK动态代理可以通过配置项spring.aop.proxy-target-classfalse来进行修…

【Linux】7.0 信号

文章目录信号的基本概念kill -l 查看信号列表信号的处理方式signal( ) 自定义处理信号信号的产生方式键盘产生进程异常&#xff08;core dump&#xff09;系统调用软件条件信号的发送&#xff08;OS&#xff09;信号常见相关名词解释进程接收处理信号原理信号集函数的使用打印p…

【Redis】3.详解分布式锁

文章目录1. 什么是分布式锁2. 分布式锁的特点3. 常见的分布式锁4. 实现分布式锁5.解决分布式锁中的原子性问题5.1 Lua脚本5.2 使用Java代码调用Lua脚本实现原子性1. 什么是分布式锁 分布式锁是指分布式系统或者不同系统之间共同访问共享资源的一种锁实现&#xff0c;其是互斥的…

【Django框架】——20 Django视图 02 路由命名和反向解析

文章目录一、 路由命名二、reverse反向解析三、通过URL模板页面进行传参四、namespace1.reverse反向解析2.url模板标签在 Django 项⽬中&#xff0c;⼀个常⻅需求是获取最终形式的 URL&#xff0c;⽐如⽤于嵌⼊⽣成的内容中&#xff08;视图和资源⽹址&#xff0c;给⽤户展示⽹…