dom4j 读取xml配置文件,根据配置文件利用反射创建对象

news/2024/10/22 7:36:53/

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>mySpring</artifactId><version>1.0</version><!--打包方式--><packaging>jar</packaging><dependencies><!--用于解析 xml 文件--><dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version></dependency><!--Java XPath 解析器XPath 是一种用于在 XML 文档中选择和查询数据的语言,可以认为它是一种针对 XML 文档的查询语言。Java 提供了许多库和工具来解析 XML,其中一个常见的用例是通过 XPath 查询指定的节点或数据,而 jaxen 提供了一种方便、灵活、易于使用、可扩展和全面的 API 来实现 XPath 查询--><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.2.0</version></dependency><!--测试依赖--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>17</source><target>17</target></configuration></plugin></plugins></build></project>

package com.example.demo.bean;public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}public User() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}
package com.example.demo.dao;public class UserDao {public void insert(){System.out.println("mysql is inserting data!");}}

package com.example.demo.service;import com.example.demo.dao.UserDao;public class UserService {private UserDao userDao;public void save(){userDao.insert();}public UserService(UserDao userDao) {this.userDao = userDao;}public UserService() {}public UserDao getUserDao() {return userDao;}public void setUserDao(UserDao userDao) {this.userDao = userDao;}
}

package com.example.spring;public interface ApplicationContext {//根据 bean 的名称获取 bean 对象Object getBean(String beanName);
}

package com.example.spring;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ClassPathXmlApplicationContext implements ApplicationContext {//存放单例bean对象private Map<String,Object> singletonObjects = new HashMap<>();//configLocation 配置文件的路径public ClassPathXmlApplicationContext(String configLocation){//解析 xml 配置文件,根据配置文件实例化bean,将bean对象存放到 singletonObjects/*org.dom4j.io.SAXReader 的作用是使用SAX解析器读取XML文件并将其转换为DOM对象模型。它可以遍历XML文档的节点树,访问和操作各个节点及其属性值,并支持XPath表达式查询*/SAXReader reader = new SAXReader();//获取类路径下资源文件的输入流InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);try {//读取配置文件, 返回DOM对象模型Document document = reader.read(in);/*selectNodes() 方法接收一个XPath表达式作为参数,返回所有匹配该表达式的节点集合(List<Node>)。这些节点可以是元素节点、属性节点或者文本节点等。*/List<Node> beans = document.selectNodes("//bean");//遍历 所有 bean 节点beans.forEach((bean) ->System.out.println(bean));} catch (DocumentException e) {e.printStackTrace();}}@Overridepublic Object getBean(String beanName) {return null;}}

myspring.xml 

<?xml version="1.0" encoding="UTF-8"?>
<beans><bean id="user" class="com.example.demo.bean.User"><property name="name" value="罗小黑"></property><property name="age" value="5"></property></bean><bean id="userDao" class="com.example.demo.dao.UserDao"></bean><bean id="userService" class="com.example.demo.service.UserService"><property name="userDao" ref="userDao"></property></bean></beans>

test

package demo;import com.example.spring.ApplicationContext;
import com.example.spring.ClassPathXmlApplicationContext;
import org.junit.Test;public class MySpring {@Testpublic void Test01(){ApplicationContext context = new ClassPathXmlApplicationContext("myspring.xml");}
}

result:

"C:\Program Files\Java\jdk-17\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 -Didea.launcher.port=50276 "-Didea.launcher.bin.path=C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\lib\idea_rt.jar;C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\plugins\junit\lib\junit-rt.jar;C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\plugins\junit\lib\junit5-rt.jar;C:\Minecloud\IDEA_workspace\spring_learn\mySpring\target\test-classes;C:\Minecloud\IDEA_workspace\spring_learn\mySpring\target\classes;C:\Users\29162\.m2\repository\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar;C:\Users\29162\.m2\repository\jaxen\jaxen\1.2.0\jaxen-1.2.0.jar;C:\Users\29162\.m2\repository\junit\junit\4.13.2\junit-4.13.2.jar;C:\Users\29162\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.application.AppMainV2 com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 demo.MySpring,Test01
org.dom4j.tree.DefaultElement@11758f2a [Element: <bean attributes: [org.dom4j.tree.DefaultAttribute@33723e30 [Attribute: name id value "user"], org.dom4j.tree.DefaultAttribute@64f6106c [Attribute: name class value "com.example.demo.bean.User"]]/>]
org.dom4j.tree.DefaultElement@69b0fd6f [Element: <bean attributes: [org.dom4j.tree.DefaultAttribute@553a3d88 [Attribute: name id value "userDao"], org.dom4j.tree.DefaultAttribute@7a30d1e6 [Attribute: name class value "com.example.demo.dao"]]/>]
org.dom4j.tree.DefaultElement@4a87761d [Element: <bean attributes: [org.dom4j.tree.DefaultAttribute@5891e32e [Attribute: name id value "uerService"], org.dom4j.tree.DefaultAttribute@cb0ed20 [Attribute: name class value "com.example.demo.service"]]/>]

Process finished with exit code 0
 

加入 log4j2 日志框架

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>mySpring</artifactId><version>1.0</version><!--打包方式--><packaging>jar</packaging><dependencies><!--用于解析 xml 文件--><dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version></dependency><!--Java XPath 解析器XPath 是一种用于在 XML 文档中选择和查询数据的语言,可以认为它是一种针对 XML 文档的查询语言。Java 提供了许多库和工具来解析 XML,其中一个常见的用例是通过 XPath 查询指定的节点或数据,而 jaxen 提供了一种方便、灵活、易于使用、可扩展和全面的 API 来实现 XPath 查询--><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.2.0</version></dependency><!--测试依赖--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--log4j-slf4j2-impl 的作用是将应用程序中使用 SLF4J 接口的日志记录请求转发到 Log4j2 实现。这样做可以方便地在应用程序中使用 SLF4J 的统一日志接口,同时还能利用 Log4j2 强大的日志级别、过滤器和输出选项等功能。--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.19.0</version></dependency><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.19.0</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>17</source><target>17</target></configuration></plugin></plugins></build></project>

log4j2 的配置文件

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?><configuration><loggers><!--level指定日志级别,从低到高的优先级:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF--><root level="DEBUG"><appender-ref ref="myspringlog"/></root></loggers><appenders><!--输出日志信息到控制台--><console name="myspringlog" target="SYSTEM_OUT"><!--控制日志输出的格式--><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/></console></appenders></configuration>
package com.example.spring;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ClassPathXmlApplicationContext implements ApplicationContext {/*创建一个名为 "ClassPathXmlApplicationContext" 的日志记录器对象并赋值给 logger 变量。通过在程序中使用该 logger 对象输出日志信息,可以方便地追踪代码执行过程中产生的日志事件,从而帮助开发者进行调试和排查错误。*/private static final Logger logger = LoggerFactory.getLogger(ClassPathXmlApplicationContext.class);//存放单例bean对象private Map<String,Object> singletonObjects = new HashMap<>();//configLocation 配置文件的路径public ClassPathXmlApplicationContext(String configLocation){//解析 xml 配置文件,根据配置文件实例化bean,将bean对象存放到 singletonObjects/*org.dom4j.io.SAXReader 的作用是使用SAX解析器读取XML文件并将其转换为DOM对象模型。它可以遍历XML文档的节点树,访问和操作各个节点及其属性值,并支持XPath表达式查询*/SAXReader reader = new SAXReader();//获取类路径下资源文件的输入流InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);try {//读取配置文件, 返回DOM对象模型Document document = reader.read(in);/*selectNodes() 方法接收一个XPath表达式作为参数,返回所有匹配该表达式的节点集合(List<Node>)。这些节点可以是元素节点、属性节点或者文本节点等。*/List<Node> beans = document.selectNodes("//bean");//遍历 所有 bean 节点beans.forEach((bean) ->{//向下转型,为了使用Element的方法Element beanElement = (Element)bean;//获取 bean 的 idString id = beanElement.attributeValue("id");//获取 classNameString className = beanElement.attributeValue("class");//输出日志消息 是在INFO级别 level 记录消息,表示消息是普通的信息性质logger.info("beanName=" + id);logger.info("className" + className);});} catch (DocumentException e) {e.printStackTrace();}}@Overridepublic Object getBean(String beanName) {return null;}}

test:

package com.example;import com.example.spring.ClassPathXmlApplicationContext;public class Myspring {public static void main(String[] args) {new ClassPathXmlApplicationContext("myspring.xml");}
}

结果: 

2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=user
2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - classNamecom.example.demo.bean.User
2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=userDao
2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - classNamecom.example.demo.dao
2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=uerService
2023-05-20 09:37:18 114 [main] INFO com.example.spring.ClassPathXmlApplicationContext - classNamecom.example.demo.service

Process finished with exit code 0
 

反射创建对象并加入map中 曝光

package com.example.spring;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ClassPathXmlApplicationContext implements ApplicationContext {/*创建一个名为 "ClassPathXmlApplicationContext" 的日志记录器对象并赋值给 logger 变量。通过在程序中使用该 logger 对象输出日志信息,可以方便地追踪代码执行过程中产生的日志事件,从而帮助开发者进行调试和排查错误。*/private static final Logger logger = LoggerFactory.getLogger(ClassPathXmlApplicationContext.class);//存放单例bean对象private Map<String,Object> singletonObjects = new HashMap<>();//configLocation 配置文件的路径public ClassPathXmlApplicationContext(String configLocation){//解析 xml 配置文件,根据配置文件实例化bean,将bean对象存放到 singletonObjects/*org.dom4j.io.SAXReader 的作用是使用SAX解析器读取XML文件并将其转换为DOM对象模型。它可以遍历XML文档的节点树,访问和操作各个节点及其属性值,并支持XPath表达式查询*/SAXReader reader = new SAXReader();//获取类路径下资源文件的输入流InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);try {//读取配置文件, 返回DOM对象模型Document document = reader.read(in);/*selectNodes() 方法接收一个XPath表达式作为参数,返回所有匹配该表达式的节点集合(List<Node>)。这些节点可以是元素节点、属性节点或者文本节点等。*/List<Node> beans = document.selectNodes("//bean");//遍历 所有 bean 节点beans.forEach((bean) ->{//向下转型,为了使用Element的方法Element beanElement = (Element)bean;//获取 bean 的 idString id = beanElement.attributeValue("id");//获取 classNameString className = beanElement.attributeValue("class");//输出日志消息 是在INFO级别 level 记录消息,表示消息是普通的信息性质logger.info("beanName=" + id);logger.info("className=" + className);try {//加载类,得到类 对象Class<?> clazz = Class.forName(className);//反射 获取无参构造方法Constructor<?> constructor = clazz.getDeclaredConstructor();//利用无参构造方法创建对象Object o = constructor.newInstance();//将对象加入map集合 曝光singletonObjects.put(id,o);logger.info(singletonObjects.toString());} catch (Exception e) {e.printStackTrace();}});} catch (DocumentException e) {e.printStackTrace();}}@Overridepublic Object getBean(String beanName) {return null;}}

 结果:

"C:\Program Files\Java\jdk-17\bin\java.exe" -Didea.launcher.port=59706 "-Didea.launcher.bin.path=C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Minecloud\IDEA_workspace\spring_learn\mySpring\target\classes;C:\Users\29162\.m2\repository\org\dom4j\dom4j\2.1.3\dom4j-2.1.3.jar;C:\Users\29162\.m2\repository\jaxen\jaxen\1.2.0\jaxen-1.2.0.jar;C:\Users\29162\.m2\repository\org\apache\logging\log4j\log4j-core\2.19.0\log4j-core-2.19.0.jar;C:\Users\29162\.m2\repository\org\apache\logging\log4j\log4j-api\2.19.0\log4j-api-2.19.0.jar;C:\Users\29162\.m2\repository\org\apache\logging\log4j\log4j-slf4j2-impl\2.19.0\log4j-slf4j2-impl-2.19.0.jar;C:\Users\29162\.m2\repository\org\slf4j\slf4j-api\2.0.0\slf4j-api-2.0.0.jar;C:\Minecloud\IDEA_2019\IntelliJ IDEA 2019.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMainV2 com.example.Myspring
2023-05-20 10:25:51 298 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=user
2023-05-20 10:25:51 298 [main] INFO com.example.spring.ClassPathXmlApplicationContext - className=com.example.demo.bean.User
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - {user=User{name='null', age=0}}
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=userDao
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - className=com.example.demo.dao.UserDao
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - {user=User{name='null', age=0}, userDao=com.example.demo.dao.UserDao@3e78b6a5}
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - beanName=uerService
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - className=com.example.demo.service.UserService
2023-05-20 10:25:51 314 [main] INFO com.example.spring.ClassPathXmlApplicationContext - {uerService=com.example.demo.service.UserService@41f69e84, user=User{name='null', age=0}, userDao=com.example.demo.dao.UserDao@3e78b6a5}

Process finished with exit code 0
 

调用set方法注入属性

package com.example.spring;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ClassPathXmlApplicationContext implements ApplicationContext {/*创建一个名为 "ClassPathXmlApplicationContext" 的日志记录器对象并赋值给 logger 变量。通过在程序中使用该 logger 对象输出日志信息,可以方便地追踪代码执行过程中产生的日志事件,从而帮助开发者进行调试和排查错误。*/private static final Logger logger = LoggerFactory.getLogger(ClassPathXmlApplicationContext.class);//存放单例bean对象private Map<String,Object> singletonObjects = new HashMap<>();//configLocation 配置文件的路径public ClassPathXmlApplicationContext(String configLocation){//解析 xml 配置文件,根据配置文件实例化bean,将bean对象存放到 singletonObjects/*org.dom4j.io.SAXReader 的作用是使用SAX解析器读取XML文件并将其转换为DOM对象模型。它可以遍历XML文档的节点树,访问和操作各个节点及其属性值,并支持XPath表达式查询*/SAXReader reader = new SAXReader();//获取类路径下资源文件的输入流InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(configLocation);try {//读取配置文件, 返回DOM对象模型Document document = reader.read(in);/*selectNodes() 方法接收一个XPath表达式作为参数,返回所有匹配该表达式的节点集合(List<Node>)。这些节点可以是元素节点、属性节点或者文本节点等。*/List<Node> beans = document.selectNodes("//bean");//遍历 所有 bean 节点beans.forEach((bean) ->{//向下转型,为了使用Element的方法Element beanElement = (Element)bean;//获取 bean 的 idString id = beanElement.attributeValue("id");//获取 classNameString className = beanElement.attributeValue("class");//输出日志消息 是在INFO级别 level 记录消息,表示消息是普通的信息性质logger.info("beanName=" + id);logger.info("className=" + className);try {//加载类,得到类 对象Class<?> clazz = Class.forName(className);//反射 获取无参构造方法Constructor<?> constructor = clazz.getDeclaredConstructor();//利用无参构造方法创建对象Object o = constructor.newInstance();//将对象加入map集合 曝光singletonObjects.put(id,o);logger.info(singletonObjects.toString());} catch (Exception e) {e.printStackTrace();}});//再次遍历bean标签,给属性赋值beans.forEach((bean) ->{try {//向下转型,为了使用Element的方法Element beanElement = (Element) bean;//获取 bean 的 idString id = beanElement.attributeValue("id");//获取 classNameString className = beanElement.attributeValue("class");//加载类Class<?> clazz = Class.forName(className);//获取该标签下的所有 property 标签List<Element> properties = beanElement.elements("property");//遍历所有的 property 标签properties.forEach(property ->{try {//获取属性名String propertyName = property.attributeValue("name");logger.info("propertyName=" + propertyName);//获取 value 属性的值String value = property.attributeValue("value");//获取 ref 的值String ref = property.attributeValue("ref");//通过 propertyName 获取 set 方法名String methodName = "set" + propertyName.toUpperCase().charAt(0) + propertyName.substring(1);logger.info("methodName=" + methodName);//反射获取属性Field field = clazz.getDeclaredField(propertyName);//反射获取 set 方法Method method = clazz.getDeclaredMethod(methodName,field.getType());//value 转换类型后的值Object actualValue = null;if(value != null) {if( String.class != field.getType() ){//根据属性的类名将 value 转换为 相应的类型actualValue = convertValue( value, field.getType() );//调用 set 方法method.invoke( singletonObjects.get(id), actualValue );}else{method.invoke( singletonObjects.get(id), value );}}else if(ref != null){//调用 set 方法method.invoke( singletonObjects.get(id), singletonObjects.get(ref) );}}catch (Exception e){e.printStackTrace();}});}catch (Exception e){e.printStackTrace();}});} catch (DocumentException e) {e.printStackTrace();}}@Overridepublic Object getBean(String beanName) {return this.singletonObjects.get(beanName);}//将 value转换为 type 类型public static Object convertValue(String value, Class<?> type) {// Check if the type is a primitive typeif (type.isPrimitive()) {// Get the corresponding wrapper classtype = getWrapperClass(type);}try {// Get the valueOf method of the wrapper classMethod valueOfMethod = type.getMethod("valueOf", String.class);// Invoke the valueOf method to convert the value to the desired typereturn valueOfMethod.invoke(null, value);} catch (Exception e) {throw new RuntimeException("Error converting value", e);}}private static Class<?> getWrapperClass(Class<?> primitiveType) {if (primitiveType == boolean.class) return Boolean.class;if (primitiveType == byte.class) return Byte.class;if (primitiveType == char.class) return Character.class;if (primitiveType == short.class) return Short.class;if (primitiveType == int.class) return Integer.class;if (primitiveType == long.class) return Long.class;if (primitiveType == float.class) return Float.class;if (primitiveType == double.class) return Double.class;throw new IllegalArgumentException("Not a primitive type");}}

 test

package com.example;import com.example.demo.bean.User;
import com.example.demo.service.UserService;
import com.example.spring.ApplicationContext;
import com.example.spring.ClassPathXmlApplicationContext;public class Myspring {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("myspring.xml");User user = (User) context.getBean("user");System.out.println( user.toString() );UserService userService = (UserService)context.getBean("userService");userService.getUserDao().insert();}
}

结果:


http://www.ppmy.cn/news/76997.html

相关文章

【Nginx】缓存集成

文章目录 缓存的概念Nginx的web缓存服务Nginx缓存设置的相关指令Nginx缓存设置案例Nginx缓存的清除方式一:删除对应的缓存目录方式二:使用第三方扩展模块 Nginx设置资源不缓存 缓存的概念 缓存就是数据交换的缓冲区(称作:Cache),当用户要获取数据的时候&#xff0c;会先从缓存…

5GNR——RACH随机接入流程(1):随机接入的原因

1、随机接入触发原因 1- Initial access from RRC_IDLE; 2- RRC Connection Re-establishment procedure; 3- DL or UL data arrival during RRC_CONNECTED when UL synchronisation status is “non-synchronised”; 4- UL data arrival during RRC_CONNECTED when there are …

uCOSii信号量

uCOSii信号量 主要用来测试使用uCOSii“创建信号量,发送信号量&#xff0c;接收信号量,删除信号量”。 学习uCOSii一定要先了解os_cfg.h文件。 信号量管理函数如下&#xff1a; OSSemAccept() 无条件地等待请求一个信号量函数,中断服务子程序只能用OSSemAccept()而不能用OS…

effective c++ 19 设置class犹如设计type

effective c 19 设置class犹如设计type 哎&#xff0c;该讲也是一个非常宽泛的话题。需要程序员在工作中不断积累。作者在本节中也没有举任何的例子&#xff0c;本节的话题实在太大&#xff0c; 本人的建议就是去多看看优秀的开源项目&#xff0c; 看看别人是如何设计类的&…

LabVIEWCompactRIO 开发指南33 测试和调试LabVIEW FPGA代码

LabVIEWCompactRIO 开发指南33 测试和调试LabVIEW FPGA代码 如前所述&#xff0c;应在仿真模式下开发LabVIEWFPGA VI&#xff0c;以快速迭代设计并避免冗长的编译时间。当需要测试和调试VI时&#xff0c;可以保持仿真模式或利用其他几个选项。应该根据功能验证与性能的要求以…

Shell免交互操作(少年不可得之物以后也不会得到了)

文章目录 一、Here Document 免交互1.免交互定义2.格式和使用方法 二、Expect 免交互1.简介2.格式和使用&#xff08;1&#xff09;声明解释器&#xff08;2&#xff09;spawn&#xff08;跟踪&#xff09;&#xff08;3&#xff09;expect&#xff08;期望&#xff09;&#x…

一个团队管理者应该干什么?

文章目录 一、前言二、搞好团队气氛三、上下都要处理好四、做好计划并监督执行&#xff0c;控制风险。五、小结 一、前言 话说管理这个东西是猪有猪的想法&#xff0c;狗有狗的想法。所以不会有一个定论&#xff0c;总是有人定义这个管理方式&#xff0c;那个管理方式。看的管…

leetcode88.合并两个有序数组

88. 合并两个有序数组 题目叙述&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注…