代理模式概述

1.代理模式概述

学习内容

1)概述

为什么要有 “代理” ?

  • 生活中就有很多例子,比如委托业务,黄牛(票贩子)等等
  • 代理就是被代理者没有能力或者不愿意去完成某件事情,需要找个人代替自己去完成这件事,这才是“代理”存在的原因。
  • 例如要租房子,房产中介可以在我们住房前代理我们找房子。中介就是代理,而自己就是被代理了。

在代码设计中,代理模式作用主要就是让 “被代理对象” 的某个方法执行之或者执行之加入其他增强逻辑。

前增强 : 例如获取当前时间被代理对象调用方法后增强 : 例如获取当前时间计算方法执行的时间

2)代理的前提条件 : 掌握 !

  • 抽象角色 :声明功能
  • 代理角色 :实现抽象功能 , 完成代理逻辑
  • 被代理角色 :实现抽象功能

意味着被代理角色和代理角色有着共同的父类型(既抽象角色) , 例如我要租房子, 我只能找房产中介, 不能找票贩子
在这里插入图片描述

  • 代理模式存在两种实现方式:

    • 静态代理
    • 动态代理

知识小结

  1. 请说出代码中代理模式的作用?

    代理角色对 被代理就角色某个方法执行的前或者后进行 功能增强
    
  2. 请说出代理模式中的三个角色?

    抽象角色
    代理角色
    被代理角色
    

==============================================================================================================

1.1 静态代理

学习目标

  • 能够写出静态代理模式代码

内容讲解

  • 静态代理是由程序员创建 或 工具生成代理类的源码,再编译代理类。

    在程序运行前就已经存在代理类的字节码文件,代理类和被代理类的关系在运行前就确定了。

    简单理解 : 在程序运行之前 , 代理类就存在了,这就是静态代理 ; 动态代理是程序运行时动态生成代理类

  • 静态代理实现的步骤 :

    • 存在一个抽象角色
    • 定义被代理角色
    • 定义代理,增强被代理角色的功能

案例实践 :

  • 以现实中经纪人代理明星

已知存在接口:

// 1.抽象角色
interface Star {// 真人秀方法double liveShow(double money);void sleep();
}

定义被代理类:

  • 定义王宝强类,实现Star方法
// - 定义被代理角色(宝强)
class BaoQiang implements Star {@Overridepublic double liveShow(double money) {System.out.println("宝强参加了一个真人秀活动赚了" + money + "钱");return money;}@Overridepublic void sleep() {System.out.println("宝强累了 , 睡觉...");}
}

定义代理类:

  • 定义宋喆经纪人类
// - 定义代理角色(宋喆),增强被代理角色的功能
class SongZhe implements Star {private BaoQiang baoQiang;public SongZhe(BaoQiang baoQiang) {this.baoQiang = baoQiang;}@Overridepublic double liveShow(double money) {// 前增强System.out.println("宋喆帮宝强拉了一个真人秀的活动,获取佣金" + money * 0.8 + "元");// 被代理角色的功能double result = baoQiang.liveShow(money * 0.2);// 后增强System.out.println("宋喆帮宝强把赚的钱存了起来...");return result;}@Overridepublic void sleep() {// 前增强System.out.println("宋喆帮宝强定了一家五星级大酒店");baoQiang.sleep();// 后增强System.out.println("宋喆帮宝强退房...");}
}

定义测试类进行测试

/*静态代理实现的步骤  :- 存在一个抽象角色- 定义被代理角色(宝强)- 定义代理角色(宋喆),增强被代理角色的功能*/
public class StaticAgentDemo {public static void main(String[] args) {// 创建被代理角色 , 没有任何增强BaoQiang baoQiang = new BaoQiang();double result = baoQiang.liveShow(1000);System.out.println(result);baoQiang.sleep();System.out.println("===========================");// 创建代码角色对象 , 可以对被代理角色功能做前后增强SongZhe songZhe = new SongZhe(baoQiang);double result2 = songZhe.liveShow(1000);System.out.println(result2);songZhe.sleep();}
}

关系图 :

在这里插入图片描述
宋喆和宝强都有共同的父类型。他们的业务方法都是一样。

静态代理和装饰模式的对比 :

​ BufferedRead(FileRead)

​ 1 装饰设计模式是功能扩展功能,在原有的功能基础之上增加了新的功能

​ 2 而代理主要对功能的前后做了增强

知识小结

  • 请问什么叫做静态代理?

    代码执行前,已经确定了代理的代码逻辑。

2. 动态代理

学习目标

  • 能够知道什么是动态代理
  • 能够熟悉动态代理相关API
  • 能够熟悉动态代理代码执行流程

内容讲解

1)概述

在实际开发过程中往往我们自己不会去创建代理类而是通过JDK提供的Proxy类在程序运行时,运用反射机制动态创建而成

这就是我们所谓的动态代理

与静态代理之间的区别,在于不用自己写代理类

虽然我们不需要自己定义代理类创建代理对象

但是我们要定义对被代理对象直接访问方法的拦截,原因就是对拦截的方法做增强

动态代理技术在框架中使用居多,例如:很快要学到的数据库框架MyBatis框架等一些主流框架技术(Spring,SpringMVC)中都使用了动态代理技术。

2)API学习

Proxy类
  • java.lang.reflect.Proxy类提供了用于创建动态代理类和对象的静态方法

​ 它还是由这些方法创建的所有动态代理类的超类(代理类的父类是Proxy)。

public static Object newProxyInstance (ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h ) 获取代理对象的方法 - 返回值:该方法返回就是动态生成的代理对象
- 参数列表说明:1. ClassLoader loader 	- 定义代理类的类加载器2. Class<?>[] interfaces 	- 代理类要实现的接口列表,要求与被代理类的接口一样。3. InvocationHandler h 	- 就是具体实现代理逻辑的接口
InvocationHandler接口

源码 :

interface InvocationHandler{public Object invoke(Object proxy, Method method, Object[] args);  //代理逻辑
}

java.lang.reflect.InvocationHandler是代理对象的实际处理代理逻辑的接口,具体代理实现逻辑在其 invoke 方法中。所有代理对象调用的方法,执行是都会经过invoke。因此如果要对某个方法进行代理增强,就可以在这个invoke方法中进行定义。

方法说明如下:

public Object invoke(Object proxy, Method method, Object[] args);1. 返回值:方法被代理后执行的结果。
2. 参数列表:1. proxy  - 就是代理对象2. method - 代理对象调用的方法3. args   - 代理对象调用方法传入参数值的对象数组.

3)代码实践

将经纪人代理明星的案例使用动态代理实现

  1. 把父接口定义
  2. 定义被代理类:宝强
  3. 动态生成代理类
  4. 定义代理逻辑
package com.itheima.dynamicproxy_demo;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 测试类
/*1 Proxy类 :public static Object newProxyInstance (ClassLoader loader,Class<?>[] interfaces,InvocationHandler h ) 获取代理对象的方法- 返回值:该方法返回就是动态生成的代理对象- 参数列表说明:1. ClassLoader loader 	- 定义代理类的类加载器2. Class<?>[] interfaces 	- 代理类要实现的接口列表,要求与被代理类的接口一样。3. InvocationHandler h 	- 就是具体实现代理逻辑的接口2 InvocationHandler接口public Object invoke(Object proxy, Method method, Object[] args);1. 返回值:方法被代理后执行的结果。2. 参数列表:1. proxy  - 就是代理对象2. method - 代理对象调用的方法3. args   - 代理对象调用方法传入参数值的对象数组.*/
public class DynamicProxyDemo {public static void main(String[] args) {// Proxy.newProxyInstance(被代理角色的类加载器 , 被代理角色实现的所有接口 , 处理器);// 被代理角色的类加载器ClassLoader classLoader = BaoQiang.class.getClassLoader();// 被代理角色实现的所有接口Class<?>[] interfaces = BaoQiang.class.getInterfaces();// 创建被代理角色对象BaoQiang baoQiang = new BaoQiang();// 代理角色 , 动态生成Star songZhe = (Star) Proxy.newProxyInstance(classLoader, interfaces, new MyInvocationHandler(baoQiang));// 代理角色调用liveShow方法songZhe.liveShow(1000);songZhe.sleep();}
}// 定义InvocationHandler接口的实现类
class MyInvocationHandler implements InvocationHandler {private BaoQiang baoQiang;public MyInvocationHandler(BaoQiang baoQiang) {this.baoQiang = baoQiang;}// invoke什么时候会执行????// 代理对象调用功能 , 就会触发invoke方法// 此方法对被代理角色的功能做增强// method : 代理对象调用功能就会触发invoke方法 , invoke方法中的method代表的就是调用的方法对象@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("liveShow")) {// 代理角色对象调用liveShow方法 , 此位置会拦截// 前增强System.out.println("宋喆帮宝强拉了一个真人秀的活动,获取佣金" + (double) args[0] * 0.8 + "元");Object result = method.invoke(baoQiang, (double) args[0] * 0.2);// 后增强System.out.println("宋喆帮宝强把赚的钱存了起来...");return result;} else if (method.getName().equals("sleep")) {// 代理角色对象调用sleep方法 , 此位置会拦截method.invoke(baoQiang);} else {// 除了liveShow和sleep方法 , 会执行else代码块中的内容}return null;}
}//  1 抽象角色
interface Star {double liveShow(double money);void sleep();
}// 2 定义被代理角色(宝强)
class BaoQiang implements Star {@Overridepublic double liveShow(double money) {System.out.println("宝强参加了一个真人秀活动赚了" + money + "钱");return money;}@Overridepublic void sleep() {System.out.println("宝强累了 , 睡觉...");}
}

动态代理调用流程:

在这里插入图片描述

小结

  1. 什么是动态代理?
    在代码执行前,没有代理类,代理类是在程序运行的时候动态生成.

    Proxy.newProxyInstance
    
  2. 动态代理有什么好处?
    动态代理可以为 “被代理对象” 的所有接口的所有方法做代理,动态代理可以在不改变方法源码的情况下,实现对方法功能的增强。

  3. 动态代理相关的API有哪些?

    Proxypublic static Object newProxyInstance(类加载器,接口列表,调用处理器)类加载器 = 被代理对象.getClass().getClassLoader();接口列表 = 被代理对象.getClass().getInterfaces();调用处理器 = new InvocationHandler(){   实现  invoke 方法 };InvocationHandlerpublic Object invoke(代理对象,方法对象,方法的实参类别) 该方法执行时机是,代理对象调用方法时触发执行
    
  4. 动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。

  5. 缺点 :只能针对接口的实现类做代理对象,普通类是不能做代理对象的。

    后面框架学习的时候会接触到CGLib(Code Genneration Library ): 可以实现对类的代理。

    数据库连接池与JDBC Template

数据库连接池

1. 概念:其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。2. 好处:1. 节约资源2. 用户访问高效3. 实现:1. 标准接口:DataSource   javax.sql包下的1. 方法:* 获取连接:getConnection()* 归还连接:Connection.close()。如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接2. 一般我们不去实现它,有数据库厂商来实现1. C3P0:数据库连接池技术2. Druid:数据库连接池实现技术,由阿里巴巴提供的4. C3P0:数据库连接池技术* 步骤:1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,* 不要忘记导入数据库驱动jar包2. 定义配置文件:* 名称: c3p0.properties 或者 c3p0-config.xml* 路径:直接将文件放在src目录下即可。3. 创建核心对象 数据库连接池对象 ComboPooledDataSource4. 获取连接: getConnection* 代码://1.创建数据库连接池对象DataSource ds  = new ComboPooledDataSource();//2. 获取连接对象Connection conn = ds.getConnection();
5. Druid:数据库连接池实现技术,由阿里巴巴提供的1. 步骤:1. 导入jar包 druid-1.0.9.jar2. 定义配置文件:* 是properties形式的* 可以叫任意名称,可以放在任意目录下3. 加载配置文件。Properties4. 获取数据库连接池对象:通过工厂来来获取  DruidDataSourceFactory5. 获取连接:getConnection* 代码://3.加载配置文件Properties pro = new Properties();InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");pro.load(is);//4.获取连接池对象DataSource ds = DruidDataSourceFactory.createDataSource(pro);//5.获取连接Connection conn = ds.getConnection();2. 定义工具类1. 定义一个类 JDBCUtils2. 提供静态代码块加载配置文件,初始化连接池对象3. 提供方法1. 获取连接方法:通过数据库连接池获取连接2. 释放资源3. 获取连接池的方法* 代码:public class JDBCUtils {//1.定义成员变量 DataSourceprivate static DataSource ds ;static{try {//1.加载配置文件Properties pro = new Properties();pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));//2.获取DataSourceds = DruidDataSourceFactory.createDataSource(pro);} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();}}/*** 获取连接*/public static Connection getConnection() throws SQLException {return ds.getConnection();}/*** 释放资源*/public static void close(Statement stmt,Connection conn){/* if(stmt != null){try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if(conn != null){try {conn.close();//归还连接} catch (SQLException e) {e.printStackTrace();}}*/close(null,stmt,conn);}

		    public static void close(ResultSet rs , Statement stmt, Connection conn){

		        if(rs != null){try {rs.close();} catch (SQLException e) {e.printStackTrace();}}

		        if(stmt != null){try {stmt.close();} catch (SQLException e) {e.printStackTrace();}}if(conn != null){try {conn.close();//归还连接} catch (SQLException e) {e.printStackTrace();}}}/*** 获取连接池方法*/public static DataSource getDataSource(){return  ds;}}

Spring JDBC

* Spring框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
* 步骤:1. 导入jar包2. 创建JdbcTemplate对象。依赖于数据源DataSource* JdbcTemplate template = new JdbcTemplate(ds);3. 调用JdbcTemplate的方法来完成CRUD的操作* update():执行DML语句。增、删、改语句* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value 将这条记录封装为一个map集合* 注意:这个方法查询的结果集长度只能是1* queryForList():查询结果将结果集封装为list集合* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中* query():查询结果,将结果封装为JavaBean对象* query的参数:RowMapper* 一般我们使用BeanPropertyRowMapper实现类。可以完成数据到JavaBean的自动封装* new BeanPropertyRowMapper<类型>(类型.class)* queryForObject:查询结果,将结果封装为对象* 一般用于聚合函数的查询4. 练习:* 需求:1. 修改1号数据的 salary 为 100002. 添加一条记录3. 删除刚才添加的记录4. 查询id为1的记录,将其封装为Map集合5. 查询所有记录,将其封装为List6. 查询所有记录,将其封装为Emp对象的List集合7. 查询总记录数* 代码:import cn.itcast.domain.Emp;import cn.itcast.utils.JDBCUtils;import org.junit.Test;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.jdbc.core.RowMapper;import java.sql.Date;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import java.util.Map;public class JdbcTemplateDemo2 {//Junit单元测试,可以让方法独立执行

			    //1. 获取JDBCTemplate对象private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());/*** 1. 修改1号数据的 salary 为 10000*/@Testpublic void test1(){//2. 定义sqlString sql = "update emp set salary = 10000 where id = 1001";//3. 执行sqlint count = template.update(sql);System.out.println(count);}/*** 2. 添加一条记录*/@Testpublic void test2(){String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";int count = template.update(sql, 1015, "郭靖", 10);System.out.println(count);}/*** 3.删除刚才添加的记录*/@Testpublic void test3(){String sql = "delete from emp where id = ?";int count = template.update(sql, 1015);System.out.println(count);}/*** 4.查询id为1001的记录,将其封装为Map集合* 注意:这个方法查询的结果集长度只能是1*/@Testpublic void test4(){String sql = "select * from emp where id = ? or id = ?";Map<String, Object> map = template.queryForMap(sql, 1001,1002);System.out.println(map);//{id=1001, ename=孙悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}}/*** 5. 查询所有记录,将其封装为List*/@Testpublic void test5(){String sql = "select * from emp";List<Map<String, Object>> list = template.queryForList(sql);for (Map<String, Object> stringObjectMap : list) {System.out.println(stringObjectMap);}}/*** 6. 查询所有记录,将其封装为Emp对象的List集合*/@Testpublic void test6(){String sql = "select * from emp";List<Emp> list = template.query(sql, new RowMapper<Emp>() {@Overridepublic Emp mapRow(ResultSet rs, int i) throws SQLException {Emp emp = new Emp();int id = rs.getInt("id");String ename = rs.getString("ename");int job_id = rs.getInt("job_id");int mgr = rs.getInt("mgr");Date joindate = rs.getDate("joindate");double salary = rs.getDouble("salary");double bonus = rs.getDouble("bonus");int dept_id = rs.getInt("dept_id");emp.setId(id);emp.setEname(ename);emp.setJob_id(job_id);emp.setMgr(mgr);emp.setJoindate(joindate);emp.setSalary(salary);emp.setBonus(bonus);emp.setDept_id(dept_id);return emp;}});

			        for (Emp emp : list) {System.out.println(emp);}}/*** 6. 查询所有记录,将其封装为Emp对象的List集合*/@Testpublic void test6_2(){String sql = "select * from emp";List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));for (Emp emp : list) {System.out.println(emp);}}/*** 7. 查询总记录数*/@Testpublic void test7(){String sql = "select count(id) from emp";Long total = template.queryForObject(sql, Long.class);System.out.println(total);}}

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

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

相关文章

Hugging News #0814: Llama 2 学习资源大汇总

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…

地址解析协议-ARP

ARP协议 无论网络层使用何种协议&#xff0c;在实际网络的链路上传输数据帧时&#xff0c;最终必须使用硬件地址 地址解析协议&#xff08;Address Resolution Protocol&#xff0c;ARP&#xff09;&#xff1a;完成IP地址到MAC地址的映射&#xff0c;每个主机都有一个ARP高速缓…

企业权限管理(十)-用户详情

用户详情 UserController findById方法 Controller RequestMapping("/user") public class UserController {Autowiredprivate IUserService userService;//查询指定id的用户RequestMapping("/findById.do")public ModelAndView findById(String id) thro…

htmlCSS-----弹性布局案例展示

目录 前言 效果展示 ​编辑 代码 思路分析 前言 上一期我们学习了弹性布局&#xff0c;那么这一期我们用弹性布局来写一个小案例&#xff0c;下面看代码&#xff08;上一期链接html&CSS-----弹性布局_灰勒塔德的博客-CSDN博客&#xff09; 效果展示 代码 html代码&am…

商用汽车转向系统常见故障解析

摘要&#xff1a; 车辆转向系统是用于改变或保持汽车行驶方向的专门机构。其作用是使汽车在行驶过程中能按照驾驶员的操纵意图而适时地改变其行驶方向&#xff0c;并在受到路面传来的偶然冲击及车辆意外地偏离行驶方向时&#xff0c;能与行驶系统配合共同保持车辆继续稳定行驶…

新能源汽车电控系统

新能源汽车电控系统主要分为&#xff1a;三电系统电控系统、高压系统电控系统、低压系统电控系统 三电系统电控系统 包括整车控制器、电池管理系统、驱动电机控制器等。 整车控制器VCU 整车控制器作为电动汽车中央控制单元&#xff0c;是整个控制系统的核心&#xff0c;也是…

实验二十九、正弦波变锯齿波电路

一、题目 将峰值为 1 V 1\,\textrm V 1V、频率为 100 Hz 100\,\textrm{Hz} 100Hz 的正弦波输入电压&#xff0c;变换为峰值为 5 V 5\,\textrm V 5V、频率为 200 Hz 200\,\textrm {Hz} 200Hz 的锯齿波电压。利用 Multisim 对所设计的电路进行仿真、修改&#xff0c;直至满足…

CentOS防火墙操作:开启端口、开启、关闭、配置

一、基本使用 启动&#xff1a; systemctl start firewalld 关闭&#xff1a; systemctl stop firewalld 查看状态&#xff1a; systemctl status firewalld 开机禁用 &#xff1a; systemctl disable firewalld 开机启用 &#xff1a; systemctl enable firewalld systemctl是…

actuator/prometheus使用pushgateway上传jvm监控数据

场景 准备 prometheus已经部署pushgateway服务&#xff0c;访问{pushgateway.server:9091}可以看到面板 实现 基于springboot引入支持组件&#xff0c;版本可以 <!--监控检查--><dependency><groupId>org.springframework.boot</groupId><artifa…

Blazor简单教程(1.1):Razor基础语法

文章目录 前言基本文件配置引入Layout组件 语法介绍pagecodeRazor 语法[ 显式表达和隐式表达](https://learn.microsoft.com/zh-cn/aspnet/core/mvc/views/razor?viewaspnetcore-7.0#explicit-razor-expressions) 绑定简单绑定双向绑定带参数的函数绑定 依赖注入 前言 Blazor…

07 线程学习

一 qt线程角色 子线程完成与UI线程无关的工作,并且能够保持与UI线程通信 二 qt中线程 在QT中,对于 线程操作也是提供类(QThread)来进行封装,然后再学习该类的API接口 参数用途Header:#include qmake:QT += coreInherits:QObject //继承于QObject从官方文档可以看出,如果一…

CDH6.3.2搭建HIVE ON TEZ

参考 https://blog.csdn.net/ly8951677/article/details/124152987 ----配置hive运行引擎 在/etc/hive/conf/hive-site.xml中修改如下&#xff1a; hive.execution.engine mr–>tez hive.execution.engine 设为tez或者运行代码的时候&#xff1a; set hive.execution.eng…

Linux 路由三大件

对于 Linux 网络&#xff0c;好奇心强的同学一定思考过两个问题&#xff1a; 当我们发出一个包的时候&#xff0c;Linux 是如何决策该从哪个网卡&#xff08;假设有多个网卡&#xff09;、哪个下一跳发出这个包&#xff0c;用什么 IP 作为 source......当 Linux 收到一个包时&a…

pywinauto结合selenium实现文件上传

简介 PC端-Windows上的元素识别可用viewWizard工具 PC端-Windows上的元素操作可用pywinauto库 浏览器上网页的元素识别可用selenium 安装 pip installer pywinauto 使用须知 pywinauto官方文档 确定app的可访问技术 1、win32 API(backend“win32”) 一般是MFC、VB6、VCL…

小程序-uni-app:hbuildx uni-app 安装 uni-icons 及使用

一、官方文档找到uni-icons uni-app官网 二、下载插件 三、点击“打开HBuildX” 四、选择要安装的项目 五、勾选要安装的插件 六、安装后&#xff0c;项目插件目录 根目录uni_modules目录下增加uni-icons、uni-scss 七、引入组件&#xff0c;使用组件 <uni-icons type&qu…

【声波】声波在硼酸、硫酸镁 (MgSO4) 和纯水中的吸收研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

POST请求负载form-data表单数据需要同步修改header的Content-type

需要读公司的一个接口&#xff0c;显示负载是“表单数据” 一开始没注意类型&#xff0c;按照公司其他接口的情况用了json&#xff0c;结果返回的数据时间阶段没有体现dct的要求&#xff0c;脚本如下&#xff08;错误示范&#xff09; from requests import post from json im…

docker学习

配置数据卷容器 1、创建启动c3数据卷容器&#xff0c;使用-v参数&#xff0c;设置数据卷 docker run -it --namec3 -v /volume centos:7 /bin/bash 2、创建启动c1 c2容器&#xff0c;使用--volumes-from 参数设置数据卷 docker run -it --namec1 --volumes-from c3 centos:7 /…

超声波一体气象站的介绍

超声波一体气象站集风速、风向、温湿度、噪声采集、PM2.5和 PM10、CO2、大气压力、光照于一体&#xff0c;采用标准 ModBus-RTU 通信协议&#xff0c;RS485信号输出方式&#xff0c;通信距离可达 2000 米&#xff0c;数据能够通过 485 通信的方式上传至客户的监控软件或 PLC 组…

JVM——分代收集理论和垃圾回收算法

一、分代收集理论 1、三个假说 弱分代假说&#xff1a;绝大多数对象都是朝生夕灭的。 强分代假说&#xff1a;熬过越多次垃圾收集过程的对象越难以消亡。 这两个分代假说共同奠定了多款常用的垃圾收集器的一致的设计原则&#xff1a;收集器应该将Java堆划分出不同的区域&…