五十、Spring

1.Spring概述 

1.1 Spring是什么

Spring是分层的 Java SE/EE应用 full-stack(全栈式) 轻量级开源框架。

提供了表现层 SpringMVC和持久层 Spring JDBC Template以及 业务层 事务管理等众多的企业级应用 技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE 企业应用开源框架。

两大核心:以 IOC(Inverse Of Control:控制反转)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。

1.2 Spring发展历程

* EJB1997 年,IBM提出了EJB 的思想1998 年,SUN制定开发标准规范 EJB1.01999 年,EJB1.1 发布2001 年,EJB2.0 发布2003 年,EJB2.1 发布2006 年,EJB3.0 发布
* SpringRod Johnson( Spring 之父)改变Java世界的大师级人物2002年编著《Expert one on one J2EE design and development》指出了JavaEE和EJB组件框架中的存在的一些主要缺陷;提出普通java类依赖注入更为简单的解决方案。2004年编著《Expert one-on-one J2EE Development without EJB》阐述了JavaEE开发时不使用EJB的解决方式(Spring 雏形)同年4月spring1.0诞生
2006年10月,发布 Spring2.0
2009年12月,发布 Spring3.0
2013年12月,发布 Spring4.0
2017年9月, 发布最新 Spring5.0 通用版(GA)1.3 Spring优势
1)方便解耦,简化开发Spring就是一个容器,可以将所有对象创建和关系维护交给Spring管理什么是耦合度?对象之间的关系,通常说当一个模块(对象)更改时也需要更改其他模块(对象),这就是耦合,耦合度过高会使代码的维护成本增加。要尽量解耦
2)AOP编程的支持Spring提供面向切面编程,方便实现程序进行权限拦截,运行监控等功能。
3)声明式事务的支持通过配置完成事务的管理,无需手动编程
4)方便测试,降低JavaEE API的使用Spring对Junit4支持,可以使用注解测试
5)方便集成各种优秀框架不排除各种优秀的开源框架,内部提供了对各种优秀框架的直接支持

1.4 Spring体系结构 

2.初识IOC

2.1 概述 

控制反转(Inverse Of Control)不是什么技术,而是一种设计思想。它的目的是指导我们设计出更 加松耦合的程序。

控制:在java中指的是对象的控制权限(创建、销毁)

反转:指的是对象控制权由原来 由开发者在类中手动控制 反转到 由Spring容器控制 

举个例子

* 传统方式 之前我们需要一个userDao实例,需要开发者自己手动创建 new UserDao(); 
* IOC方式 现在我们需要一个userDao实例,直接从spring的IOC容器获得,对象的创建权交给了spring控制 

2.2 自定义IOC容器

2.2.1 介绍

需求

实现service层与dao层代码解耦合

步骤分析

1. 创建java项目,导入自定义IOC相关坐标

2. 编写Dao接口和实现类

3. 编写Service接口和实现类

4. 编写测试代码

2.2.2 实现 

1)创建java项目,导入自定义IOC相关坐标

<dependencies><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.1.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

2)编写Dao接口和实现类 

public interface UserDao {public void save();
}
public class UserDaoImpl implements UserDao {public void save() {System.out.println("保存成功了...");}
}
3)编写Service接口和实现类 
public interface UserService {public void save();
}public class UserServiceImpl implements UserService {private UserDao userDao;public void save(){userDao = new UserDaoImpl();userDao.save();}
}

4)编写测试代码

public class UserTest {@Testpublic void testSave() throws Exception {UserService userService = new UserServiceImpl();userService.save();}
}

5)问题

当前service对象和dao对象耦合度太高,而且每次new的都是一个新的对象,导致服务器压力过大。

解耦合的原则是编译期不依赖,而运行期依赖就行了。 

把所有需要创建对象的信息定义在配置文件中 

<?xml version="1.0" encoding="UTF-8" ?>
<beans><bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"></bean>
</beans>

7)编写BeanFactory工具类 

public class BeanFactory {/* 声明集合用来保存bean  */private static Map<String, Object> ioc = new HashMap<>();static {try {/* 1.读取配置文件 */InputStream in =BeanFactory.class.getClassLoader().getResourceAsStream("beans.xml");/* 2.解析xml */SAXReader saxReader = new SAXReader();Document document = saxReader.read(in);/* 3.编写xpath表达式 */String xpath = "//bean";/* 4.获取所有的bean标签 */List<Element> list = document.selectNodes(xpath);/* 5.遍历并创建对象实例,设置到map集合中 */for (Element element : list) {String id = element.attributeValue("id");String className = element.attributeValue("class");Object object = Class.forName(className).newInstance();ioc.put(id, object);}} catch (Exception e) {e.printStackTrace();}}// 获取指定id的对象实例public static Object getBean(String beandId) {return ioc.get(beandId);}
}

8)修改UserServiceImpl实现类 

public class UserServiceImpl implements UserService {private UserDao userDao;public void save() throws Exception{userDao = (UserDao) BeanFactory.getBean("userDao");userDao.save();}
}

2.2.3 知识小结

* 其实升级后的BeanFactory就是一个简单的Spring的IOC容器所具备的功能。
* 之前我们需要一个userDao实例,需要开发者自己手动创建 new UserDao();
* 现在我们需要一个userdao实例,直接从spring的IOC容器获得,对象的创建权交给了spring控制
* 最终目标:代码解耦合

3.Spring快速入门

3.1 介绍

需求:借助spring的IOC实现service层与dao层代码解耦合

步骤分析

1. 创建java项目,导入spring开发基本坐标
2. 编写Dao接口和实现类
3. 创建spring核心配置文件
4. 在spring配置文件中配置 UserDaoImpl
5. 使用spring相关API获得Bean实例

3.2 实现

1)创建java项目,导入spring开发基本坐标

<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.5.RELEASE</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency>
</dependencies>

2)编写Dao接口和实现类

 
public interface UserDao {public void save();
}public class UserDaoImpl implements UserDao {public void save() {System.out.println("保存成功了...");}
}

3)创建spring核心配置文件 applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

4)在spring配置文件中配置 UserDaoImpl

//详细内容 见上3
<beans ...><bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"></bean>
</beans>

5)使用spring相关API获得Bean实例

public class UserTest {@Testpublic void testSave() throws Exception {/* 加载同时保存bean 到容器中 */ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");/* 直接从容器中获取 */UserDao userDao = (UserDao) applicationContext.getBean("userDao");userDao.save();}
}

3.3 知识小结

Spring的开发步骤

1. 导入坐标
2. 创建Bean
3. 创建applicationContext.xml
4. 在配置文件中进行Bean配置
5. 创建ApplicationContext对象,执行getBean

4.Spring相关API

4.1 API继承体系介绍 

Spring的API体系异常庞大,我们现在只关注两个BeanFactory和ApplicationContext

4.2 BeanFactory

BeanFactory是 IOC 容器的核心接口,它定义了IOC的基本功能。

特点:在第一次调用getBean()方法时,创建指定对象的实例 

@Test
public void test2(){/*  核心接口,不会创建bean对象存到容器中 */BeanFactory xmlBeanFactory = new XmlBeanFactory(
new ClassPathResource("applicationContext.xml"));/* getBean的时候才真正创建bean对象 */
IUserDao userDao = (IUserDao) xmlBeanFactory.getBean("userDao");userDao.save();
}

4.3 ApplicationContext

代表应用上下文对象,可以获得spring中IOC容器的Bean对象。

特点:在spring容器启动时,加载并创建所有对象的实例

常用实现类 

1. ClassPathXmlApplicationContext 
它是从类的根路径下加载配置文件 推荐使用这种。 
2. FileSystemXmlApplicationContext 它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。 
3. AnnotationConfigApplicationContext 当使用注解配置容器对象时,需要使用此类来创建 spring 容器。它用来读取注解。

测试代码

@Test
public void test1(){/* 获取到了spring上下文对象,借助上下文对象可以获取到IOC容器中的bean对象 ,加载的同时就创建了bean对象存到容器中 */ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");//ApplicationContext fileSystemXmlApplicationContext = new FileSystemXmlApplicationContext("D:\\xxx\\xxx\\src\\main\\resources\\applicationContext.xml");/* 使用上下文对象从IOC容器中获取到了bean对象1.根据beanid在容器中找对应的bean对象 *///IUserDao userDao = (IUserDao) classPathXmlApplicationContext.getBean("userDao");/*2.根据类型在容器中进行查询:有可能报错的情况:根据当前类型匹配到多个实例 */IUserDao userDao = classPathXmlApplicationContext.getBean("userDao",IUserDao.class);/* 调用方法 */userDao.save();}

常用方法 

1. Object getBean(String name);根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
2. <T> T getBean(Class<T> requiredType);根据类型从容器中匹配Bean实例,当容器中相同类型的Bean有多个时,则此方法会报错。
3. <T> T getBean(String name,Class<T> requiredType);根据Bean的id和类型获得Bean实例,解决容器中相同类型Bean有多个情况。

5.Spring配置文件

5.1 Bean标签基本配置 

<bean id="" class=""></bean>
* 用于配置对象交由Spring来创建。
* 基本属性:id:Bean实例在Spring容器中的唯一标识class:Bean的全限定名
* 默认情况下它调用的是类中的 无参构造函数,如果没有无参构造函数则不能创建成功。

5.2 Bean标签范围配置 

<bean id="" class="" scope=""></bean>

scope属性指对象的作用范围,取值如下:

 

1. 当scope的取值为singleton时 Bean的实例化个数:1个 Bean的实例化时机:当Spring核心文件被加载时,实例化配置的Bean实例 Bean的生命周期: 对象创建:当应用加载,创建容器时,对象就被创建了 对象运行:只要容器在,对象一直活着 对象销毁:当应用卸载,销毁容器时,对象就被销毁了 2. 当scope的取值为prototype时 Bean的实例化个数:多个 Bean的实例化时机:当调用getBean()方法时实例化Bean Bean的生命周期: 对象创建:当使用对象时,创建新的对象实例 对象运行:只要对象在使用中,就一直活着 对象销毁:当对象长时间不用时,被 Java 的垃圾回收器回收了

5.3 Bean生命周期配置 

<bean id="" class="" scope="" init-method="" destroy-method=""></bean>
* init-method:指定类中的初始化方法名称
* destroy-method:指定类中销毁方法名称

<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>

public class UserDaoImpl implements UserDao {public void save() {System.out.println("保存成功了...");}public void init(){System.out.println("init");}public void destroy(){System.out.println("destroy");}
}

5.4 Bean实例化三种方式

  • 无参构造方法实例化
  • 工厂静态方法实例化
  • 工厂普通方法实例化

5.4.1 无参构造方法实例化

它会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败

<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"/>

5.4.2 工厂静态方法实例化 

应用场景

依赖的jar包中有个A类,A类中有个静态方法m1,m1方法的返回值是一个B对象。如果我们频繁使用 B对象,此时我们可以将B对象的创建权交给spring的IOC容器,以后我们在使用B对象时,无需调用A类 中的m1方法,直接从IOC容器获得。

public class StaticFactoryBean {public static UserDao createUserDao(){return new UserDaoImpl();}
}
<bean id="userDao" class="com.aaa.factory.StaticFactoryBean"
factory-method="createUserDao" />

5.4.3 工厂普通方法实例化 

应用场景

依赖的jar包中有个A类,A类中有个普通方法m1,m1方法的返回值是一个B对象。如果我们频繁使用 B对象

此时我们可以将B对象的创建权交给spring的IOC容器,以后我们在使用B对象时,无需调用A类中的m1 方法,直接从IOC容器获得。

public class DynamicFactoryBean {public UserDao createUserDao(){return new UserDaoImpl(); } 
}

<bean id="dynamicFactoryBean" class="com.aaa.factory.DynamicFactoryBean"/>
<bean id="userDao" factory-bean="dynamicFactoryBean" factory-method="createUserDao"/>

5.5 Bean依赖注入概述

依赖注入 DI(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。

在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。 

那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。简单的说,就是通 过框架把持久层对象传入业务层,而不用我们自己去获取。

5.6 Bean依赖注入方式

5.6.1 构造方法

在UserServiceImpl中创建有参构造


public class UserServiceImpl implements UserService {private UserDao userDao;public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void save() {userDao.save();}
}

配置Spring容器调用有参构造时进行注入 

<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.aaa.service.impl.UserServiceImpl">
<!-- <constructor-arg index="0" type="com.aaa.dao.UserDao" ref="userDao"/> -->
<constructor-arg name="userDao" ref="userDao"/>
</bean>

测试

ApplicationContext classPathXmlApplicationContext = 
new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = 
(UserService) classPathXmlApplicationContext.getBean("userService");
userService.save();

5.6.2 set方法 

在UserServiceImpl中创建set方法


public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}@Overridepublic void save() {userDao.save();}
}

配置Spring容器调用set方法进行注入

<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.aaa.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"/>
</bean>

5.6.3 P命名空间注入(了解)

P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件 中,如下:

首先,需要引入P命名空间:

xmlns:p="http://www.springframework.org/schema/p"

其次,需要修改注入方式:

<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.aaa.service.impl.UserServiceImpl"
p:userDao-ref="userDao"/>

5.7 Bean依赖注入的数据类型

上面操作,都是注入Bean对象,除了对象的引用可以注入,普通数据类型和集合都可以在容器中进行注入。 

注入数据的三种数据类型

1. 普通数据类型

2. 引用数据类型

3. 集合数据类型

其中引用数据类型,此处就不再赘述了,之前的操作都是对UserDao对象的引用进行注入的。下面将 以set方法注入为例,演示普通数据类型和集合数据类型的注入。

5.7.1 注入普通数据类型


public class User {private String username;private String age;public void setUsername(String username) {this.username = username;}public void setAge(String age) {this.age = age;}
}
<bean id="user" class="com.aaa.domain.User"><property name="username" value="fyh"/><property name="age" value="18"/>
</bean>

测试

ApplicationContext classPathXmlApplicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");User user =classPathXmlApplicationContext.getBean("user",User.class);
System.out.println(user);

5.7.2 注入集合数据类型

1)List集合注入


public class UserDaoImpl implements UserDao {private List<Object> list;public void setList(List<Object> list) {this.list = list;}  public void save() {System.out.println(list);System.out.println("保存成功了...");}
}
<bean id="user" class="com.aaa.domain.User"><property name="username" value="jack"/><property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"><property name="list"><list><value>aaa</value><ref bean="user"></ref></list></property>
</bean>

2)Set集合注入

public class UserDaoImpl implements UserDao {private Set<Object> set;public void setSet(Set<Object> set) {this.set = set;}public void save() {System.out.println(set);System.out.println("保存成功了...");}
}
<bean id="user" class="com.aaa.domain.User"><property name="username" value="jack"/><property name="age" value="18"/></bean><bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"><property name="set"><set><value>bbb</value><ref bean="user"></ref></set></property>
</bean>

3)Array数组注入


public class UserDaoImpl implements UserDao {private Object[] array;public void setArray(Object[] array) {this.array = array;}public void save() {System.out.println(Arrays.toString(array));System.out.println("保存成功了...");}
}
<bean id="user" class="com.aaa.domain.User"><property name="username" value="jack"/><property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"><property name="array"><array><value>ccc</value><ref bean="user"></ref></array></property>
</bean>

4)Map集合注入

public class UserDaoImpl implements UserDao {private Map<String, Object> map;public void setMap(Map<String, Object> map) {this.map = map;}public void save() {System.out.println(map);System.out.println("保存成功了...");}
}
<bean id="user" class="com.aaa.domain.User"><property name="username" value="jack"/><property name="age" value="18"/>
</bean>
<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"><property name="map"><map><entry key="k1" value="ddd"/><entry key="k2" value-ref="user"></entry></map></property>
</bean>

5)Properties配置注入 


public class UserDaoImpl implements UserDao {private Properties properties;public void setProperties(Properties properties) {this.properties = properties;}public void save() {System.out.println(properties);System.out.println("保存成功了...");}
}
<bean id="userDao" class="com.aaa.dao.impl.UserDaoImpl"><property name="properties"><props><prop key="k1">v1</prop><prop key="k2">v2</prop><prop key="k3">v3</prop></props></property>
</bean>

5.8 配置文件模块化

实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分 配置拆解到其他配置文件中,也就是所谓的配置文件模块化。

1)并列的多个配置文件

ApplicationContext act = new ClassPathXmlApplicationContext("beans1.xml","beans2.xml","..."); 

2)主从配置文件

<import resource="applicationContext-xxx.xml"/>

注意: 同一个xml中不能出现相同名称的bean,如果出现会报错 多个xml如果出现相同名称的bean,不会报错,但是后加载的会覆盖前加载的bean

5.9 知识小结 

<bean>标签:创建对象并放到spring的IOC容器id属性:在容器中Bean实例的唯一标识,不允许重复class属性:要实例化的Bean的全限定名scope属性:Bean的作用范围,常用是Singleton(默认)和prototype
<constructor-arg>标签:属性注入name属性:属性名称value属性:注入的普通属性值ref属性:注入的对象引用值
<property>标签:属性注入name属性:属性名称value属性:注入的普通属性值ref属性:注入的对象引用值<list><set><array><map><props>
<import>标签:导入其他的Spring的分文件

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

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

相关文章

4个顶级WooCommerce商城多站点库存同步WordPress插件

经营几家网上商店是令人兴奋的。但是&#xff0c;这也是一项艰巨的工作&#xff0c;尤其是当您意识到需要同步这些商店的库存时。好消息是&#xff0c;有 WooCommerce 多站点库存同步插件和选项可以加快速度。 WooCommerce 多站点网络可让您将所有在线商店无缝地安置在一个屋檐…

【Tauri + React 实战】VCluster - 了解技术选型与开发环境配置

VCluster A React Tauri App as visualizer of apps cluster on windows. 背景介绍 VCluster是一个在开发环境下&#xff0c;用以对一系列应用集群&#xff08;如分布式、微服务&#xff09;进行可视化管理的桌面应用程序&#xff0c;目标是实现类似 docker-compose 那样的集…

TabBar和TabBarView实现顶部滑动导航

home.dart子页面主要代码&#xff1a; import package:flutter/material.dart;class HomePage extends StatefulWidget {const HomePage({super.key});overrideState<HomePage> createState() > _HomePageState(); }class _HomePageState extends State<HomePage&…

windows环境hadoop报错‘D:\Program‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

Hadoop版本为2.7.3&#xff0c;在环境配置好后&#xff0c;检查hadoop安装版本&#xff0c;报如标题所示错误&#xff0c;尝试网上主流的几种方法均无效。 错误&#xff1a;windows环境hadoop报错’D:\Program’ 不是内部或外部命令,也不是可运行的程序 或批处理文件。 错误方…

【技巧】Maven重复依赖分析查找

【技巧】Maven重复依赖分析查找 遇到奇葩的错误可以考虑是不是依赖冲突了 比如同一段代码 再这个项目中好好的 另一个项目中不能用等 idea安装插件 maven helper 打开pom文件 输入要查找的依赖 将不用的排除掉 右键排除即可

在阿里云平台注册一个域名

我们访问阿里云官网 阿里云 然后 我们右上角点击登录 然后 按正常操作流程登录 登录成功后 我们点击控制台 我们将鼠标 移入 右上角 图片指向的位置 我们点击域名 进入界面后点击注册域名 在输入框中输入域名内容 然后 按回车 然后弹出的列表 我们可以选一个未注册的 点击…

Druid-排查conditionDoubleConstAllow配置问题(double const condition)

Druid-排查conditionDoubleConstAllow配置问题(double const condition) 报错信息 Caused by: java.sql.SQLException: sql injection violation, dbType postgresql, druid-version 1.2.18, double const condition : SELECT * FROM test where 11 AND TRUE AND TRUE关键词&…

正则表达式概念以及语法的使用

目录 1.概念 2. 为什么使用正则表达式&#xff1f; 3. 语法 1.普通字符 非打印字符 2. 特殊字符 3. 限定符 4. 定位符 5. 运算优先级 3.匹配规则 1. 基本模式匹配 2. 字符簇 3. 确定重复出现 1.概念 正则表达式(Regular Expression)是一种文本模式&#xff0c;包…

如何使用自动化构造随机路由模型

为什么要仿真随机路由&#xff1f; 路由器测试中&#xff0c;为了最大程度还原现网路由情况&#xff0c;评估路由器在现网环境下稳定工作各项指标&#xff0c;需要对导入路由进行离散仿真&#xff0c;目前路由仿真可分为导入路由与生成路由两种方式&#xff0c;导入路由需要现…

think-on-graph: 基于知识图谱的大模型推理

概述 本文的研究背景是大规模语言模型在复杂推理任务中存在困难并展示了较低的性能&#xff0c;特别是在需要知识的追溯能力、及时性和准确性的场景中。 过去的方法主要面临两个问题&#xff1a;推理不负责任容易生成虚构或带有有害文本&#xff0c;以及模型在预训练阶段无法…

基于IPC-CFX的点对点通信C#

IPC-CFX有两种主要的通信方式&#xff0c;可以通过RabbitMQ发布和订阅&#xff0c;也可以通过request和response进行点对点的通信&#xff0c;本文主要讲的是点对点的通信方式。 在vscode里建立新的dotnet项目&#xff0c;可以通过终端输入dotnet new console来建立&#xff0c…

LCD—STM32液晶显示(2.使用FSMC模拟8080时序)

目录 使用STM32的FSMC模拟8080接口时序 FSMC简介 FSMC NOR/PSRAM中的模式B时序图 用FSMC模拟8080时序 重点&#xff1a;HADDR内部地址与FSMC地址信号线的转换&#xff08;实现地址对齐&#xff09; 使用STM32的FSMC模拟8080接口时序 ILI9341的8080通讯接口时序可以由STM32使…

北邮国院物联网 Microprocessor 微处理器笔记

Introduction-随便聊 嵌入式系统是什么&#xff1f;专用的计算机系统。为专门功能可能对计算机架构&#xff0c;外设等做出一些取舍。 通常的限制&#xff1a;Cost&#xff08;比如大量部署传感器节点&#xff09;&#xff0c;Size and weight limits&#xff08;特定应用场景…

配置Hadoop_0

配置Hadoop_0 1配置Hadoop100模板虚拟机1.1配置Hadoop100模板虚拟机硬件1.2配置Hadoop100模板虚拟机软件1.3配置Hadoop100模板虚拟机IP地址1.4配置Hadoop100模板虚拟机主机名称/主机名称映射1.5配置Hadoop100模板虚拟机远程操作工具 1配置Hadoop100模板虚拟机 Hadoop100 内存…

TRT4-trt-integrate - 1 YOLOV5导出、编译、推理

模型导出 修改Image的Input动态维度 首先可以看到这个模型导出的时候Input有三个维度都是动态&#xff0c;而我们之前说过只需要一个batch维度是动态&#xff0c;所以要在export的export onnx 进行修改&#xff0c;将 torch.onnx.export(model, im, f, verboseFalse, opset_ver…

华为云子网路由表作用及价值

子网路由表 子网路由表作用云专线、VPN的配置与子网路由表强关联&#xff0c;本质是在相应的子网路由表中添加了一条路由Nat路由表问题地址变更问题snat和dnat 子网路由表作用 子网内部作为一个二层网络&#xff0c;通过mac地址互通&#xff0c;不通过路由互通。跨子网&#x…

实时网络更改检测

未经授权的配置更改可能会对业务连续性造成严重破坏&#xff0c;这就是为什么使用实时更改检测来检测和跟踪更改是网络管理员的一项关键任务。尽管可以手动跟踪更改&#xff0c;但此方法往往非常耗时&#xff0c;并且通常会导致人为错误&#xff0c;例如在跟踪时错过关键网络设…

企业需要一个数字体验平台(DXP)吗?

数字体验平台是一个软件框架&#xff0c;通过与不同的业务系统喝解决方案集成&#xff0c;帮助企业和机构建立、管理和优化跨渠道的数字体验。帮助企业实现跨网站、电子邮件、移动应用、社交平台、电子商务站点、物联网设备、数字标牌、POS系统等传播内容&#xff0c;除了为其中…

文心一言 VS 讯飞星火 VS chatgpt (58)-- 算法导论6.4 2题

文心一言 VS 讯飞星火 VS chatgpt &#xff08;58&#xff09;-- 算法导论6.4 2题 二、试分析在使用下列循环不变量时&#xff0c;HEAPSORT 的正确性&#xff1a;在算法的第 2~5行 for 循环每次迭代开始时&#xff0c;子数组 A[1…i]是一个包含了数组A[1…n]中第i小元素的最大…

如果微信消息显示“已读”的话......

近日&#xff0c;一则 #如果微信显示已读的话# 话题冲上了微博热搜榜单。 “已读”是很多社交软件拥有的功能&#xff0c;如果对方接收并查看了消息&#xff0c;就会在消息上显示“已读”&#xff0c;但目前微信还没有推出这项功能。 对于“已读”功能&#xff0c;不少网友纷纷…