Spring框架(1)
Spring框架是Java企业级开发中最受欢迎的框架之一,它通过简化开发流程、降低耦合度,让开发者能够更专注于业务逻辑的实现。本文将带你了解Spring框架的核心概念和基本用法。
一、Spring框架简介
Spring是一个轻量级的开源Java开发框架,由Rod Johnson在2003年创建。它的核心思想是通过控制反转(IOC)和面向切面编程(AOP)来实现松耦合的应用程序设计。
Spring框架的主要优点
-
解耦简化开发:Spring就像一个大工厂,管理所有对象的创建和依赖关系
-
AOP编程支持:方便实现权限拦截、运行监控等功能
-
声明式事务管理:通过配置即可完成事务管理,无需手动编程
-
易于测试:与Junit良好集成,支持注解测试
-
集成优秀框架:支持Struts2、Hibernate、MyBatis等主流框架
-
简化JavaEE API:对JDBC、JavaMail等复杂API进行了封装
二、IOC(控制反转)核心概念
IOC(Inversion of Control)是Spring的核心,它将对象的创建权从程序员手中反转给Spring框架管理。
IOC快速入门
添加依赖:在pom.xml中添加Spring核心依赖
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies>
创建接口和实现类
package com.qcbyjy.service;public interface UserService {public void hello();
}package com.qcbyjy.service;public class UserServiceImpl implements UserService {public void hello(){System.out.println("Hello IOC");}
}
配置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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--IOC管理bean--><bean id="userService" class="com.qcbyjy.service.UserServiceImpl"/></beans>
把log4j.properties的配置文件拷贝到resources目录下,做为log4j的日志配置 文件。
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
测试代码
package com.qcbyjy.test;import com.qcbyjy.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo1 {@Testpublic void run1(){//使用Spring的工厂ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");//通过工厂获得类UserService userService=(UserService) applicationContext.getBean("userService");userService.hello();}
}
ApplicationContext接口,工厂的接口,使用该接口可以获取到具体的Bean对 象。该接口下有两个具体的实现类。
springCould配置中心
ClassPathXmlApplicationContext,加载类路径下的Spring配置文件。 FileSystemXmlApplicationContext,加载本地磁盘下的Spring配置文件。
三、Spring框架的Bean管理的配置文件方式
id属性,Bean起个名字,在约束中采用ID的约束,唯一,取值要求:必须以字 母开始,可以使用字母、数字、连字符、下划线、句话、冒号id:不能出现特殊 字符。
class 属性,Bean 对象的全路径。
scope 属性,scope属性代表Bean的作用范围。
Bean的作用范围
-
singleton
:单例(默认),整个应用只创建一个实例 -
prototype
:多例,每次请求都创建一个新实例 -
request
:Web应用中,每个HTTP请求创建一个实例 -
session
:Web应用中,同一个HTTP Session共享一个实例
Bean 对象的创建和销毁的两个属性配置
说明:Spring初始化bean或销毁bean时,有时需要作一些处理工作,因此spring 可以在创建和拆卸bean的时候调用bean的两个生命周期方法
init-method,当 bean 被载入到容器的时候调用init-method属性指定的方法
destroy-method,当 bean 从容器中删除的时候调用destroy-method属性指定 的方法
实例化Bean对象的三种方式
默认是无参数的构造方法(默认方式,基本上使用)
<bean id="us" class="com.qcbyjy.service.UserServiceImpl" />
静态工厂实例化方式
package com.qcbyjy.demo1;import com.qcbyjy.service.UserService;
import com.qcbyjy.service.UserServiceImpl;public class StaticFactory {//静态工厂方式public static UserService createUs(){System.out.println("\"通过静态工厂的方式创建UserServiceImpl对\n" +"象...");//编写很多业务逻辑,权限校验return new UserServiceImpl();}
}
<bean id="us" class="com.qcbyjy.demo1.StaticFactory" factory-method="createUs"/>
实例工厂实例化方式
package com.qcbyjy.demo1;import com.qcbyjy.service.UserService;
import com.qcbyjy.service.UserServiceImpl;public class Dfactory {public UserService createUs(){//动态工厂方式System.out.println("实例化工厂的方式....");return new UserServiceImpl();}
}
<bean id="dfactory" class="com.qcbyjy.demo1.Dfactory"/><bean id="us" factory-bean="dfactory" factory-method="createUs"/>
四、DI(依赖注入)
DI(Dependency Injection)是IOC的具体实现方式,Spring在创建Bean时,动态地将依赖对象注入到组件中。
三种依赖注入方式
set方法注入(最常用)
package com.qcbyjy.service;public interface OrderService {void saveOrder();
}package com.qcbyjy.service;import com.qcbyjy.dao.OrderDao;public class OrderServiceImpl implements OrderService {private OrderDao orderDao;public void setOrderDao(OrderDao orderDao){this.orderDao=orderDao;}private String msg;private int age;public OrderDao getOrderDao() {return orderDao;}public void setMsg(String msg) {this.msg = msg;}public void saveOrder(){System.out.println("业务层:保存订单..."+msg+"-"+age);//调用orderDao.saveOrder();}public void setAge(int age) {this.age = age;}
}package com.qcbyjy.dao;public interface OrderDao {void saveOrder();
}
<!--DI:依赖注入--><bean id="os" class="com.qcbyjy.service.OrderServiceImpl"><property name="orderDao" ref="od"/><property name="msg" value="你好"/><property name="age" value="30"/></bean><bean id="od" class="com.qcbyjy.dao.OrderDaoImpl"></bean>
构造方法注入
package com.qcbyjy.demo2;public class Car {private String cname;private Double money;public Car(String cname,Double money){this.cname=cname;this.money=money;}@Overridepublic String toString() {return "Car{" +"cname='" + cname + '\'' +", money=" + money +'}';}
}
<bean id="car" class="com.qcbyjy.demo2.Car"><constructor-arg name="cname" value="大奔"/><constructor-arg name="money" value="400000"/></bean>
数组、集合(List,Set,Map),Properties 等的注入
package com.qcbyjy.demo3;import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;public class CollectionBean {//数组private String[] strs;public void setStrs(String[] strs){this.strs=strs;}private List<String> list;public void setList(List<String> list){this.list=list;}private Map<String ,String> map;public void setMap(Map<String,String> map){this.map=map;}private Properties properties;public void setProperties(Properties properties){this.properties=properties;}public String toString(){return"CollectionBean{"+"strs="+ Arrays.toString(strs)+",list="+list+",map="+map+",properties="+properties+'}';}
}
<bean id="collectionBean" class="com.qcbyjy.demo3.CollectionBean"><property name="strs"><array><value>美美</value><value>小凤</value></array></property><property name="list"><list><value>熊大</value><value>熊二</value></list></property><property name="map"><map><entry key="aaa" value="老王"/><entry key="bbb" value="小王"/></map></property><property name="properties"><props><prop key="username">root</prop><prop key="password">123456</prop></props></property></bean>
五、多配置文件方式
在src的目录下又多创建了一个配置文件,现在是两个核心的配置文件,那么加 载这两个配置文件的方式有两种!
//主配置文件中包含其他的配置文件:<import resource="applicationContext2.xml"/>
//工厂创建的时候直接加载多个配置文件:ApplicationContext applicationContext=new ClassPathXmlApplicationContext( "applicationContext.xml","applicationContext2.xml");
六、Spring框架开发程序的方式
1.需求:编写service和dao的类,演示代码
2.技术选择:持久层使用原始的JDBC的程序,连接池选择的是Druid连接池。创 建maven工程,导入开发的jar包
<?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.qcbyjy</groupId><artifactId>springDemo22</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.2.RELEASE</version></dependency><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><!--mysql驱动包--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency></dependencies></project>
创建数据库,创建表结构
create database spring_db;use spring_db;create table account(id int primary key auto_increment,name varchar(40),money double)character set utf8 collate utf8_general_ci;insert into account(name,money) values('aaa',1000);insert into account(name,money) values('bbb',1000);insert into account(name,money) values('ccc',1000);
编写JavaBean的类
package com.qcbyjy.domain;import java.io.Serializable;public class Account implements Serializable {private static final long serialVersionUID =7355810572012650248L;private Integer id;private String name;private Double money;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Double getMoney() {return money;}public void setMoney(Double money) {this.money = money;}@Overridepublic String toString() {return "Account{" +"id=" + id +", name='" + name + '\'' +", money=" + money +'}';}
}
编写AccountDao的接口和实现类
package com.qcbyjy.dao;import com.qcbyjy.domain.Account;import java.util.List;public interface AccountDao {public List<Account> findAll();
}package com.qcbyjy.dao;import com.qcbyjy.domain.Account;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;public class AccountDaoImpl implements AccountDao {//注入连接池对象private DataSource dataSource;public void setDataSource(DataSource dataSource){this.dataSource=dataSource;}
//查询所有数据public List<Account> findAll(){/*DruidDataSourcedataSource=newDruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring_db");dataSource.setUsername("root");dataSource.setPassword("root");*/List<Account> list=new ArrayList<Account>();Connection connection=null;PreparedStatement stmt=null;ResultSet rs=null;try{//获取连接connection=dataSource.getConnection();//编写sql语句String sql="select * from account";//预编译stmt = connection.prepareStatement(sql);//查询rs=stmt.executeQuery();//遍历,封装数据while(rs.next()){Account account=new Account();account.setId(rs.getInt("id"));account.setName(rs.getString("name"));account.setMoney(rs.getDouble("money"));list.add(account);}}catch(SQLException e){e.printStackTrace();}finally{try{connection.close();}catch(SQLException e){e.printStackTrace();}try{stmt.close();}catch(SQLException e){e.printStackTrace();}try{rs.close();}catch(SQLException e){e.printStackTrace();}}return list;}}package com.qcbyjy.service;import com.qcbyjy.domain.Account;import java.util.List;public interface AccountService {public List<Account> findAll();
}package com.qcbyjy.service;import com.qcbyjy.dao.AccountDao;
import com.qcbyjy.domain.Account;import java.util.List;public class AccountServiceImpl implements AccountService {//依赖注入private AccountDao accountDao;public void setAccountDao(AccountDao accountDao){this.accountDao=accountDao;}//查询所有数据public List<Account> findAll() {return accountDao.findAll();}
}
编写配置文件
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--配置连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///spring_db"/><property name="username" value="root"/><property name="password" value="12345"/></bean><!--管理bean--><bean id="accountService" class="com.qcbyjy.service.AccountServiceImpl"><property name="accountDao" ref="accountDao"/></bean><bean id="accountDao" class="com.qcbyjy.dao.AccountDaoImpl"><property name="dataSource" ref="dataSource"/></bean>
</beans>
编程测试程序
package com.qcbyjy.test;import com.qcbyjy.domain.Account;
import com.qcbyjy.service.AccountService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;public class Demo1 {@Testpublic void run1(){ApplicationContext ac =new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService=(AccountService) ac.getBean("accountService");//调用方法List<Account> list=accountService.findAll();for (Account account:list){System.out.println(account);}}
}
七、注解开发
随着Spring的发展,注解方式逐渐取代了XML配置,成为主流开发方式。
快速入门
IOC注解的方式依赖没有变化
编写接口和实现类
package com.qcbyjy.demo1;public interface UserService {public void hello();
}package com.qcbyjy.demo1;import org.springframework.stereotype.Component;/***<beanid="us"class="com.qcbyjy.demo2.UserServiceImpl"/>*/
//组件,作用:把当前类使用IOC容器进行管理,如果没有指定名称,默认使用类名,
//首字母是小写。userServiceImpl。或者自己指定名称
@Component(value="us")
public class UserServiceImpl implements UserService{public void hello(){System.out.println("Hello IOC注解....");}
}
在需要管理的类上添加@Component注解
@Component(value="us")
public class UserServiceImpl implements UserService{public void hello(){System.out.println("Hello IOC注解....");}
}
编写配置文件,重点是开启注解扫描。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--开启注解扫描<context:component-scanbase-package="com.qcbyjy.demo2"/>--><!--开启注解扫描com.qcbyjy.所有的包中的所有的类--><context:component-scan base-package="com.qcbyjy"/>
</beans>
编写测试方法
package com.qcbyjy.test;import com.qcbyjy.demo1.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo1 {/***IOC注解方式的入门*/@Testpublic void run1(){//工厂ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService=(UserService) ac.getBean("us");userService.hello();}}
常用注解
-
组件注解(作用相同,推荐分层使用)
-
@Component
:普通组件 -
@Controller
:表现层 -
@Service
:业务层 -
@Repository
:持久层
-
-
依赖注入注解
-
@Autowired
:按类型自动装配 -
@Qualifier
:按名称装配(需与@Autowired配合使用) -
@Resource
:Java原生注解,按名称装配 -
@Value
:注入基本类型值 -
@Autowired默认按类型进行自动装配(引用类型)
-
@Qualifier和@Autowired一起使用,强制使用名称注入
-
@ResourceJava提供的注解,也被支持。使用name属性,按名称注入 对象生命周期(作用范围)注解
-
-
作用范围注解
@Scope
:指定作用范围(singleton/prototype等)
具体的代码如下
package com.qcbyjy.demo2;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;//默认当前类名就是ID名称,首字母小写
@Component(value="c")
//@Controller
//@Service(value="c")
//@Repository(value="c")
//@Scope(value="singleton") //默认值,单例的
//@Scope(value="prototype") //多例的
public class Car {//注释注入值,属性set方法是可以省略不写的。//只有一个属性,属性的名称是value,value是可以省略不写的@Value("大奔2")private String cname;@Value(value = "400000")private Double money;//也不用提供set方法//按类型自动装配的注解,和id名称没有关系@Autowired//按id的名称注入,Qualifier不能单独使用,需要Autowired一起使用。//@Qualifier(value="person")//@ResourceJava提供的注解,按名称注入对象,属性名称是name//\@Resource(name="person")private Person person;/***Car对象创建完成后,调用init方法进行初始化操作*/@PostConstructpublic void init(){System.out.println("操作...");}/*publicStringgetCname(){returncname;}publicvoidsetCname(Stringcname){this.cname=cname;}publicDoublegetMoney(){returnmoney;}publicvoidsetMoney(Doublemoney){this.money=money;}
*/@Overridepublic String toString() {return "Car{" +"cname='" + cname + '\'' +", money=" + money +", person=" + person +'}';}
}package com.qcbyjy.demo2;import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;@Component(value="person")
public class Person {@Value("张三")private String pname;public String toString(){return"Person{"+"pname='"+pname+'\''+'}';}
}package com.qcbyjy.test;import com.qcbyjy.demo2.Car;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Demo2 {@Testpublic void run1(){ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");Car car=(Car) ac.getBean("c");System.out.println(car);}
}
纯注解开发示例
纯注解的方式是微服务架构开发的主要方式,所以也是非常的重要。纯注解的目 的是替换掉所有的配置文件。但是需要编写配置类。
编写实体类
package com.qcbyjy.demo3;import org.springframework.stereotype.Component;@Component
public class Order {@Value("北京")private String address;@Overridepublic String toString() {return "Order{" +"address='" + address + '\'' +'}';}
}
编写配置类,替换掉applicationContext.xml配置文件
packagecom.qcbyjy.demo4;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;/***Spring的配置类,替换掉applicationContext.xml**///声明当前类是配置类
@Configuration//扫描指定的包结构
@ComponentScan(value="com.qcbyjy.demo4")public class SpringConfig{}
测试方法的编写
package com.qcbyjy.test;import com.qcbyjy.demo3.Order;
import com.qcbyjy.demo3.SpringConfig;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Demo3 {/***编写程序,需要加载配置类*/@Testpublic void run1(){//创建工厂,加载配置类ApplicationContext ac=new AnnotationConfigApplicationContext(SpringConfig.class);
//获取到对象Order order=(Order) ac.getBean("order");System.out.println(order);}
}
常用的注解总结
@Configuration声明是配置类
@ComponentScan扫描具体包结构的
@Import注解Spring的配置文件可以分成多个配置的,编写多个配置类。用于 导入其他配置类
package com.qcbyjy.demo3;import org.springframework.context.annotation.Configuration;@Configuration
public class SpringConfig2 {
}package com.qcbyjy.demo3;//声明当前类是配置类
@Configuration
//扫描指定包结构
@ComponentScan(value = "com.qcbyjy.demo3")
//@ComponentScan(value={"com.qcbyjy.demo4","com.qcbyjy.demo3"})
//引入新的配置类
@Import(value={SpringConfig2.class})
public class SpringConfig {}
@Bean注解只能写在方法上,表明使用此方法创建一个对象,对象创建完成保 存到IOC容器中
package com.qcbyjy.demo3;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;import javax.sql.DataSource;//声明当前类是配置类
@Configuration
//扫描指定包结构
@ComponentScan(value = "com.qcbyjy.demo3")
//@ComponentScan(value={"com.qcbyjy.demo4","com.qcbyjy.demo3"})
//引入新的配置类
@Import(value={SpringConfig2.class})
public class SpringConfig {/***创建连接池对象,返回对象,把该方法创建后的对象存入到连接池中,使用@Bean注解解决<!--配置连接池对象--><beanid="dataSource"class="com.alibaba.druid.pool.DruidDataSource"><propertyname="driverClassName"value="com.mysql.jdbc.Driver"/><propertyname="url"value="jdbc:mysql:///spring_db"/><propertyname="username"value="root"/><propertyname="password"value="root"/></bean>**@return*/@Bean(name="dataSource")public DataSource createDataSource(){DruidDataSource dataSource=new DruidDataSource();dataSource.setDriverClassName("com.mysql.jdbc.Driver");dataSource.setUrl("jdbc:mysql:///spring_db");dataSource.setUsername("root");dataSource.setPassword("123456");return dataSource;}}
总结
Spring框架通过IOC和AOP两大核心思想,极大地简化了Java企业级开发。从最初的XML配置到现在的注解驱动开发,Spring不断演进,为开发者提供了更加便捷的开发体验。掌握Spring的基本概念和使用方法,是Java开发者必备的技能。
希望通过本文的介绍,你能对Spring框架有一个清晰的认识,并能够开始在实际项目中使用它。随着实践的深入,你会发现Spring还有更多强大的特性和技巧等待你去探索。
相关文章:
Spring框架(1)
Spring框架是Java企业级开发中最受欢迎的框架之一,它通过简化开发流程、降低耦合度,让开发者能够更专注于业务逻辑的实现。本文将带你了解Spring框架的核心概念和基本用法。 一、Spring框架简介 Spring是一个轻量级的开源Java开发框架,由Ro…...
软件安全(二)优化shellcode
我们在上一节课中所写的shellcode,其中使用到的相关的API是通过写入其内存地址来实现调用。这种方法具有局限性,如切换其他的操作系统API的内存地址就会发生变化,从而无法正常调用。 所谓的shellcode不过是在目标程序中加一个区段使得程序可…...
前端使用腾讯地图api实现定位功能
1.配置key 申请地址: https://lbs.qq.com/dev/console/key/manage 2.在项目中引入jssdk <script type"text/javascript" src"https://apis.map.qq.com/tools/geolocation/min?keykey&referermyapp"></script>使用 const g…...
单片机-STM32部分:10、串口UART
飞书文档https://x509p6c8to.feishu.cn/wiki/W7ZGwKJCeiGjqmkvTpJcjT2HnNf 串口说明 电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种: TTL电平:3.3V或5V表示1&am…...
STM32外设-串口UART
STM32外设-串口UART 一,串口简介二,串口基础概念1,什么是同步和异步/UART与USART对比2,串行与并行3,波特率 (Baud Rate)4,数据帧 (Data Frame)5,TX 和 RX 三,硬件连接1,u…...
《工业计算机硬件技术支持手册》适用于哪些人群?
《工业计算机硬件技术支持手册》于2024年出版,主要讲当前正在应用的最新计算硬件技术。包括计算机各种功能接口、扩展总线、各种国际通行的板型规格等等。书中引用的数据,全部来自国际行业技术规范,书中还融入了作者几十年的工作经验和操作技…...
element-ui时间线样式修改
element-ui时间线样式修改 前两天公司给了一个需求 要求如下图所示 需求是时间在步骤条左边,看了element-ui的文档 发现并没有参数可以设置时间在步骤条的左边 那没办法 只能自己想一想办法了 首先想到的是用样式直接改变 活不多说 直接搞 第一步 选中时间这个元素 发现了这个类…...
动态规划之背包问题:组合优化中的经典NP挑战
背包问题概念: 背包问题是一种经典的组合优化的NP问题,在计算机科学、运筹学等领域有着广泛的应用。 问题可以简单的描述为: 假设有一个容量为C的背包和n个物品,每个物品i都有重量w[i]和价值v[i]。目标是选择一些物品放入背包&…...
JavaScript 基础
JS概念 JS基础概念 JS是一种运行在客户端(浏览器)的编程语言, 实现人机交换结果 作用: 网页特效表单验证数据交互服务端编程(node.js) JS的组成 ECMAScript—javaScript语言基础Web APIs—(DOM: 页面文档对象模型)(BOM: 浏览器对象模型) JS书写 位置 内部: 写到< /body…...
Vibe Coding: 优点与缺点
如果你最近在开发圈子里,你很可能听说过这个新趋势"vibe coding"(氛围编程)。 我只能说我对此感受复杂。以下是原因。 优势 在构建新项目时,靠着氛围编程达到成功感觉很自由!但对于遗留代码来说情况就不同了,尽管也不是不可能。 实时反馈和快速迭代 Cursor(…...
小动物听力评价系统基本原理简析
小动物听力评价系统是用于评估小动物听力功能的专业设备,以下从系统组成、工作原理、评价方法等方面为你介绍: 一 系统组成 声音刺激模块:能产生不同频率、强度和类型的声音信号,如纯音、啭音、短声等,以刺激小动物的听…...
spark缓存-persist
存储级别指定 persist:可以通过传入 StorageLevel 参数来指定不同的持久化级别。常见的持久化级别有: MEMORY_ONLY:将 RDD 以 Java 对象的形式存储在 JVM 的内存中。若内存不足,部分分区将不会被缓存,需要时会重新计算…...
树初步 #1(插排串联 - 辽宁省2024CCPC)
树初步 数的基础内容可以看看树基础 - OI Wiki里面的讲解,对一些操作的基础概念介绍的很清楚; 下面直接来看例题: 插排串联 - 辽宁省CCPC 题目大意 给定一个n1个节点的有根数; 根节点(0号)是插座&…...
CDGP重点知识梳理(82个)
目 录 考点分布 考试要求 第一章 数据管理-5%...
shell脚本基础详细学习(更新中)
shell简单介绍 Shell不仅仅是充当用户与UNIX或者localhost交互的角色,还可以作为一种程序设计 语言来使用。通过Shell编程,可以实现许多非常实用的功能,提高系统管理的自动化水平。 如果有一系列经常需要使用的命令,把它存储在一…...
记录一下学习kafka的使用以及思路
下面这是kafka的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-kafka</artifactId></dependency> 我在学习的时候直接导入是没有导入成功的,我猜测大概的原因是我本…...
AT9880B北斗单模卫星定位SOC芯片
AT9880B是一款高性能北斗单模卫星导航接收机SOC单芯片,芯片集成射频前端和数字基带、北斗多频卫星信号处理引擎、电源管理功能。芯片支持接收中国北斗二号和北斗三号,支持接收B1I、B1C、B2I、B3I、B2a和 B2b等频点信号。 主要特性: 支持北斗…...
李沐《动手学深度学习》 | 多层感知机
文章目录 感知机模型《深度学习入门》的解释训练感知机损失函数的选择感知机的收敛定理:什么时候能够停下来,是不是真的可以停下来感知机的不足 多层感知模型案例引入隐藏层从线性到非线性单隐藏层-单分类案例多隐藏层 激活函数softmax函数溢出的问题 多…...
vue数据可视化开发常用库
一、常用数据可视化库 1. ECharts 特点:功能强大,支持多种图表类型,社区活跃。适用场景:复杂图表、大数据量、3D 可视化。安装:npm install echarts示例:<template><div ref"chart" c…...
CAN转ModbusTCP网关:破解电池生产线设备协议壁垒,实现全链路智能互联
在电池生产的现代工艺中,自动化和信息化水平的提高是提升产能、保障品质与安全的关键。CAN 协议作为一种广泛应用于汽车、工业控制等领域的串行通信协议,它以其高可靠性和强实时性而受到企业的青睐。而在众多工业通讯协议中,ModbusTCP作为一种…...
更新 / 安装 Nvidia Driver 驱动 - Ubuntu - 2
如果按更新 / 安装 Nvidia Driver 驱动 - Ubuntu-CSDN博客中的步骤操作后问题依旧,则查看过程中的提示信息。 如果发现有“Use sudo apt autoremove to remove them.”,则执行: #sudo apt autoremove #nvidia-smi...
技术分享 | 如何在2k0300(LoongArch架构)处理器上跑通qt开发流程
近期迅为售后团队反馈,许多用户咨询:2K0300处理器采用了LA264处理器核,若要在该处理器上运行Qt程序,由于架构发生了变化,其使用方法是否仍与ARM平台保持一致? 单纯回答‘一致’或‘不一致’缺乏说服力&…...
ubuntu 24.04 error: cannot uninstall blinker 1.7.0, record file not found. hint
最近在打python3.12的镜像,安装browser-gym的核心库,编译一个使用browswer agents的环境,然后出现了下面的问题: error: cannot uninstall blinker 1.7.0, record file not found. hint: the package was installed by debian.系…...
学习记录:DAY28
DispatcherController 功能完善与接口文档编写 前言 没什么动力说废话了。 今天来完善 DispatcherController 的功能,然后写写接口文档。 日程 早上:本来只有早八,但是早上摸鱼了,罪过罪过。下午:把 DispatcherContro…...
C# 的异步任务中, 如何暂停, 继续,停止任务
namespace taskTest {using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore new SemaphoreSlim(0, 1); // 初始为 0,Start() 启动时手动放行private read…...
html object标签介绍(用于嵌入外部资源通用标签)(已不推荐使用deprecated,建议使用img、video、audio标签)
文章目录 HTML <object> 标签详解基本语法与核心属性关键属性解析1. **data**2. **type**3. **width & height**4. **name** 嵌入不同类型的资源1. **嵌入图像**2. **嵌入音频**3. **嵌入视频**4. **嵌入 PDF** 参数传递与回退内容**参数(<param>&a…...
专题练习1
优化: 找101-200的质数: 开发验证码: 解密数字 抽奖 优化 彩票...
Uniapp编写微信小程序,使用canvas进行绘图
一、canvas文档: https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial 二、数据绘制(单位是像素): 1、绘制文本: 文字的长度超过设置的最大宽度,文字会缩在一起 ① 填充文本…...
Java高频基础面试题
Java高频基础面试题 Java基础 Java的特点是什么? 面向对象平台无关性(“一次编写,到处运行”)支持多线程自动内存管理(垃圾回收)安全性丰富的类库 JDK、JRE和JVM的区别 JDK (Java Development Kit): Java…...
U9C-SQL-采购订单视图
U9C-SQL-采购订单视图 SELECTpo.ID,CONVERT ( VARCHAR ( 10 ), po.CreatedOn, 23 ) AS 签订日期,org.Name AS 甲方,po.DocNo AS 单号,item.Code AS 料号,item.Name AS 品名,item.SPECS AS 规格,item.DescFlexField_PrivateDescSeg1 AS 图号,item.DescFlexField_PrivateDescSeg2…...
HTML字符串转换为React元素实现
HTML字符串安全转换为React元素的实现 一、背景介绍 介绍HTML字符串在Web开发中的常见场景。说明React中直接使用HTML字符串的局限性。提出将HTML字符串转换为React元素的需求。 二、首先必备的两个npm库:html-react-parser和dompurify 导入: pnpm i…...
全局异常未能正确捕获到对应的异常
自定义Validation验证器遇到的问题 抛出的异常没有能被指定的TaskValidException.class方法拦截到。故写这个原因 全局异常拦截只能拦截相同的异常。只能通过解析转入自定义的异常。自定义的异常继承的异常要是一家子的。如TaskValidException和ValidationException。这样就能在…...
LeetCode 解题思路 47(最长回文子串、最长公共子序列)
解题思路: dp 数组的含义: dp[i][j] 是否为回文子串。递推公式: dp[i][j] s.charAt(i) s.charAt(j) && dp[i 1][j - 1]。dp 数组初始化: 单字符 dp[i][i] true,双字符 dp[i][i 1] s.charAt(i) s.charA…...
P11369 [Ynoi2024] 弥留之国的爱丽丝(操作分块,DAG可达性trick)
真的神仙题。感觉学到了很多。 题意: 给你一张 n n n 个结点 m m m 条边的有向图,点编号为 1 , 2 , … , n 1,2,\dots,n 1,2,…,n。每条边的颜色为黑色或白色。一开始所有 m m m 条边都是黑色的。 你需要进行 q q q 次操作,有两种操作…...
NAT穿越
概述 IPSec协商是通过IKE完成--->ISAKMP协议完成--->由UDP封装,源目端口均为500。 NAT--->NAPT,同时转换IP和端口信息。 对端设备会查验收到的数据报文中的源IP和源端口,其中源IP可以设定为NAT转换后的IP,但是源端口无法…...
不黑文化艺术学社首席艺术家孙溟㠭浅析“雪渔派”
孙溟㠭浅析“雪渔派” 何震 字主臣 ,长卿,号雪渔,安徽婺源(今江西)人,是明代著名的篆刻家和书法家,与文彭独树一帜,实现书法与刀法的统一。 云中白鹤 笑谭间气吐霓虹 边款 其篆刻吸…...
【Linux操作系统】第一弹——Linux基础篇
文章目录 💡 一. Linux的基本常识🪔 1.1 linux网络连接三种方式🪔1.2 虚拟机的克隆🪔1.3 虚拟机的快照🪔1.4 虚拟机的迁移和删除🪔1.5 vmtools工具 💡二. Linux的目录结构🪔2.1 Linu…...
“ES7+ React/Redux/React-Native snippets“常用快捷前缀
请注意,这是一个常用的列表,不是扩展提供的所有前缀。最完整和最新的列表请参考扩展的官方文档或在 VS Code 中查看扩展的详情页面。 React (通常用于 .js, .jsx, .ts, .tsx): rfce: React Functional Component with Export Defaultrafce: React Arro…...
selenium替代----playwright
安装 好处特点:这个东西不像selenium需要固定版本的驱动 pip config set global.index-url https://mirrors.aliyun.com/pypi/simplepip install --upgrade pippip install playwright playwright installplaywright install ffmpeg (处理音视频的)验证&#x…...
2025年社交APP安全防御指南:抵御DDoS与CC攻击的实战策略
2025年,社交APP的用户规模与业务复杂度持续增长,但随之而来的DDoS与CC攻击也愈发隐蔽和智能化。攻击者通过AI伪造用户行为、劫持物联网设备,甚至利用区块链漏洞发起混合攻击,对平台稳定性与用户数据安全构成严峻挑战。本文将结合最…...
PHP会话技术
第十六章-PHP会话技术 PHP会话技术是构建动态、个性化Web应用的核心机制之一,它通过跟踪用户在网站上的连续操作状态,实现了网页间的数据持久化交互。无论是电商平台的购物车信息保存、社交媒体的用户登录状态维持,还是表单数据的跨页面传递…...
QT聊天项目DAY10
1.封装redis操作类 头文件 #ifndef REDISMANAGE_H #define REDISMANAGE_H#include "Singletion.h" #include "GlobalHead.h"class RedisManage : public Singletion<RedisManage> {friend class Singletion<RedisManage>; public:~RedisMana…...
5.0.5 变换(旋转、缩放、扭曲)
WPF变换可以产生特殊效果,如平移、旋转、扭曲。 变换类 描述TranslateTransform沿着X轴和Y轴平移ScaleTransform 沿着定义的中心点缩放RotateTransform沿着定义的中心点旋转SkewTransform 扭曲元素MatrixTransfrom提供3x3矩阵,用于定义一个自定义变换 1…...
matlab转python
1 matlab2python开源程序 https://blog.csdn.net/qq_43426078/article/details/123384265 2 网址 转换网址:https://app.codeconvert.ai/code-converter?inputLangMatlab&outputLangPython 文件比较网址:https://www.diffchecker.com/text-comp…...
什么是直播美颜SDK?跨平台安卓、iOS美颜SDK开发实战详解
时下,尤其在社交、娱乐、电商等应用场景中,一个流畅且效果自然的美颜功能往往能直接影响用户的留存率和平台的营收。要实现这些效果,美颜SDK是核心工具。那么,什么是直播美颜SDK?它的功能有哪些?如何进行跨…...
大尺寸PCB如何重塑通信与新能源产业格局
在5G通信基站与新能源电站的机房内,一块块面积超过600mm600mm的PCB板正悄然推动着技术革命。作为电子设备的核心载体,大尺寸PCB凭借其高密度集成与复杂工艺,成为通信、能源等领域的“隐形功臣”。以猎板PCB为代表的厂商,凭借宽幅曝…...
JavaSE核心知识点02面向对象编程02-04(包和导入)
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 JavaSE核心知识点02面向对象编程02-04&#…...
【漫话机器学习系列】249.Word2Vec自然语言训练模型
【自然语言处理】用 Word2Vec 将词语映射到向量空间详解 一、背景介绍 在自然语言处理(NLP)领域,我们常常需要将文本信息转化为机器能够理解和处理的形式。传统的方法,如 one-hot编码,虽然简单,但存在严重…...
CSS transition过渡属性
transition 是 CSS 中用于创建平滑动画效果的属性,它允许元素在两个状态之间平滑过渡,而不是立即改变。通过定义过渡的属性、持续时间和速度曲线,你可以实现丰富的交互体验,如悬停效果、状态切换动画等。 核心作用 平滑过渡&…...
U9C对接飞书审批流完整过程
U9C虽然很强大,但是移动办公和审批流功能并不好用,为了弥补U9C这种不足,很多的企业在使用U9C的同时再开通钉钉、飞书、企业微信这种OA管理系统,两套系统并行使用,就需要考虑U9C和OA系统数据同步的问题,最简…...