(史上最全的)Spring6框架学习教程

一、什么是Spring

1.javaWeb框架发展史

1、Servlet+JSP+JavaBean(跳转页面、业务逻辑判断、数据库查询)

2、MVC三层架构(M Model =pojo(User)V-view(USP)C-(controller-servlet))
(
web-跳转页面
service-业务逻辑判断   new UserService0;
dao-数据库查询 new UserDao();
)

3、使用EJB进行应用的开发,但是EJB是重量级框架(在使用的时候,过多的接口和依赖,侵入性强),在使用上比较麻烦 UserService imp extends

4、Struts1/Struts2+Hibernate+Spring
Spring
(
web-跳转页面 Struts
service-业务逻辑判断
dao-数据库查询Hibernate
)--------SSH

5、SpringMVC+Mybatis+Spring
(
web-跳转页面 SpringMVC(出现BUG,使用毕竟麻烦)
service-业务逻辑判断
dao-数据库查询 myBatis
)-------SSM
6、SpringBoot开发,约定大于配置SSM搭建架构需要大量XML配置文件

7、mvvm架构
Model(模型):负责处理应用程序的数据逻辑,比如数据库读写等数据源的操作。
View(视图):负责显示数据(即模型层的数据)并且接收用户操作界面的界面。
ViewModel(视图模型):作为Model和View之间的桥梁,从Model层获取数据后,处理并返回给View层显示。ViewModel 还负责处理View层的用户界面操作,将相关事件转发到Model层。

2.Spring框架简介

Spring框架英文全称Spring framework,是由Spring团队研发的模块化、轻量级开源框架。其主要目的 是为了简化项目开发。在项目开发中,可以说没有刻意使用Spring,却处处有着Spring存在,用官网对Spring框架的介绍:Spring框架核心功能包含依赖注入、事务管理、Web应用、数据访问、消息发送等等。

Spring框架的设计理念基于以下核心原则:
轻量级设计:

轻量级设计是Spring框架的首要原则之一。通过采用轻量级的设计,Spring能够在应用程序开发中提供高效、简单的解决方案。相比于其他重型框架,Spring注重简洁性,使得开发者能够更专注于业务逻辑的实现,而不必被繁琐的框架细节所困扰。

非侵入性的设计:

Spring框架强调非侵入性,这意味着开发者不需要修改已有的Java类来适应框架,从而保持了代码的整洁性和可维护性。非侵入性设计的优势在于,开发者可以更灵活地选择使用和配置框架的功能,而不会影响到已有的代码结构。

3.Spring loC/Dl 详解

3.1、IoC/DI简介

 因为loC/Dl是 Spring Framework的基础。Spring Framework 其他所有功能都是在loC/DI 基础上 研发的。

loc: Inversion of Control控制反转
Dl:DependencyInjection 依赖注入

控制(对象创建权利)被反转:
之前:由程序员控制对象创建
UserService(new UserDao())-------->UserDao ;强耦合,再小的代码变更都会引起BUG的可能性之后:依赖Spring注入(DI)
Spring(newUserService(); new UserDao();)如果需要用到Spring管理的对象,需要依赖Spring注入(DI)

下图是没有使用IoC/DI前和使用了之后的对比图 

 

 3.2、IoC/DI的优缺点

优点:

  1. 解耦合:降低组件之间的依赖,使代码更易于理解和维护。
  2. 提高灵活性:便于在运行时替换依赖,增加系统的灵活性。
  3. 易于测试:支持单元测试,可以轻松注入模拟对象。
  4. 代码重用:相同的组件可以在不同的上下文中重用。
  5. 提高可读性:依赖关系明确,代码意图清晰。

缺点:

  1. 学习曲线:需要时间理解和掌握IoC和DI的概念。
  2. 配置复杂性:在复杂系统中,容器的配置可能变得复杂。
  3. 性能开销:可能引入一些性能开销,尤其是在应用程序启动时。
  4. 过度依赖框架:可能使得代码过于依赖特定的框架,降低可移植性。
  5. 引入复杂性:在一些简单应用中,可能会引入不必要的复杂性。

3.3、IoC/DI在项目中的应用场景

Java EE企业应用开发
IoC和DI是解耦组件之间复杂关系的利器。Spring IoC模块就是IoC模式的一种实现,通过依赖注入和AOP切面增强了为JavaBean这样的POJO对象赋予事务管理、生命周期管理等基本功能。

EJB模式
在EJB模式中,应用开发人员需要编写EJB组件,满足EJB容器的规范,才能运行在EJB容器中。Spring通过IoC提供了一个基本的JavaBean容器,管理依赖关系,降低了应用开发对传统J2EE技术规范的依赖。

Web应用程序
在Web应用程序中,控制器(Controller)和视图(View)之间的依赖关系可以通过DI来管理。这样可以降低代码的耦合度,提高可维护性和可扩展性。

服务层
在服务层中,服务类之间也可以通过DI来传递依赖对象。这种方式使得组件可以独立于其他组件进行开发和测试,提高了开发效率和代码质量。

数据访问层
在数据访问层中,DAO(Data Access Object)对象也可以通过DI来注入数据库连接信息。这种方式简化了代码的配置,使得依赖关系管理更加灵活和可维护。

二、基于Springboot快速启动Spring

点击下一步就可以创建一个SpringBoot项目并且Springboot项目我们也可以从下面图片看到SpringBoot中是依赖了Spring的。

三、SpringIoc核心容器

1.什么是Bean

1.1 Bean的简述

 Bean 是由Spring容器创建并管理的对象实例。Spring通过依赖注入(DI)和控制反转(IoC)机制管理这些对象的生命周期和依赖关系。

1.2 如何配置Bean

  1. <bean class="">
  2. @Component 写在类上面
    1. @Service
    2. @Repository
    3. @Configuration
    4. ...
  3. @Bean
    1. 写在方法上面
    2. 通常写在配置类里面
      1. @Bean方法调用另外一个@Bean方法,会从spring容器中去获取
    3. 可以干预bean的实例化过程的,jar包中的类如果要配置bean就需要用@Bean
    4. 在方法中声明的参数spring会帮我们自动注入进来
  4. @lmport
    1. @Import必须写在类上面
    2. 标记的类必须是一个bean否则不会起作用
    3. 普通类-----直接@lmport(UserService.class)普通类,把普通类注入spring
       
    4. lmportSelector-----lmportSelector -用于根据完整限定名字符串批量注入Bean
      • 定义一个类实现
      • ii.批量注册bean(通过实现selectlmports,返回bean的完整类路径字符串数组)
        ii.@lmport(实现lmportSelector.class)

1.3 实例化Bean

1.3.1 使用默认构造函数

这是最常见的方式,Spring容器会调用Bean类的默认无参构造函数来创建实例。

@Component
public class MyBean {public MyBean() {// 构造函数逻辑}
}

1.3.2 使用实例工厂方法实例化--@Bean

        可以自由的选择构造函数进行实例化

1.3.3 使用工厂类

        通过实现BeanFactory接口或使用FactoryBean接口来创建Bean实例。这种方式提供了更高的灵活性,允许你控制Bean的创建和初始化过程。

public class MyBeanFactory implements FactoryBean<MyBean> {public MyBean getObject() throws Exception {return new MyBean();}public Class<MyBean> getObjectType() {return MyBean.class;}
}

2.依赖注入

2.1 @Autowired注解

 要实现自动装配一定要用@Autowired

  1. @Bean 方法的参数默认会自动装配
  2. Bean的有参构造函数默认会自动装配(前提只能有一个有参构造函数)

@Autowired特性

@Autowired可以写在构造函数、方法、字段、参数

  1. 构造函数
    1. 如果bean只有一个有参构造函数,是省略@Autowired,会自动注入构造函数的参数。
    2. 如果有多个有参构造函数,并且没有无参构造函数:会报错, 解决:使用@Autowired指定某一个构造函数
    3. 构造函数上指定的@Autowired(required=false);会失效

     2.参数:
        如果想设置构造函数上面的参数为不是必须注入:单独去设置

        @Autowired(required = false)

        @Autowired(value = "specificBean")

2.2 @Inject和@Resource

 @Inject和@Resource
都是由JDK官方提供的。
Idea为什么不建议在字段上面使用@autowired

  1. 通过@Autowired注入私有字段不建议字段private,建议通过构造函数或者方法来进行自动注入
  2. @autowired受框架的限制

@Inject
不能设置required=false属性

<dependency><groupId>jakarta.inject</groupId><artifactId>jakarta.inject-api</artifactId><version>2.0.1</version>
</dependency>

@Resource
会先根据名字找,再根据类型找 

2.3 @Value

接受前端请求参数---pojo , 把数据库查询到的数据---pojo
user{ name ,age ..}

1. 直接值(基本类型,String等)

  @Value("ltx")private String name;@Value("18")private Integer age;

2.对外部属性(SpringBoot配置文件)文件的引用 


@Component
public class MovieRecommender {private final String catalog;public MovieRecommender(@Value("${catalog.name}") String catalog) {this.catalog = catalog;}
}

3.默认值

@Component
public class MovieRecommender {private final String catalog;public MovieRecommender(@Value("${catalog.name:defaultCatalog}") String catalog) {this.catalog = catalog;}
}

3.自动注入顺序

3.1  @Order改变自动注入顺序

 用于改变自动装配时:如果一个类型, 有多个bean, 可以List来承接装备的类型。 在List里面的bean可以通过@Order来改变。

@Component
//@Order(9)
class A implements I {public A() {System.out.println("A");}
}@Component
//@Order(0)
public class B implements I{public B() {System.out.println("B");}
}
@SpringBootTest
public class TestOrder {@Testpublic void test(@Autowired List<I> i){System.out.println(i);// 输出的A 在前面B在后面}
}
@Component
@Order(9)
class A implements I {public A() {System.out.println("A");}
}@Component
@Order(0)
public class B implements I{public B() {System.out.println("B");}
}
@SpringBootTest
public class TestOrder {@Testpublic void test(@Autowired List<I> i){System.out.println(i);// 输出的B 在前面A在后面}
}

 

3.2 @DependsOn改变Bean创建顺序

 Bean创建: (@Componet class A --b---> 容器加载 new ApplicationContext()------>
new A(); DI ... ; )


new A () 负载数据库查询
new B()数据库连接

@DependsOn("d")
public class C {public C() {System.out.println("C");}
}

4.懒加载bean

懒加载作用:
默认的bean会在启动的时候就会创建, 如果说某些Bean非常大, 如果在启动的时候就创建就会影响启动速度, 就可以把那些大的Bean设置成懒加载, 这样可以优化启动速度

懒加载Bean创建: (@Componet class A --b---> 容器加载 new ApplicationContext()------> )
用到的时候才会创建(new A(); DI ... ; ):

SpringBoot将所有的bean都配置为懒加载

spring.main.lazy-initialization=true

5.@Scope作用域

默认Bean单例(只会new 一次,不管@autowired多少次,只会创建一次)
好处: 节省内存空间(有线程安全风险)

多例Bean(只会new 一次,不管@autowired多少次,只会创建一次)
好处: 节省内存空间(有线程安全风险)

Bean 是单例的,会不会有线程安全问题?

线程安全问题: 多线程并发的情况下, 同时对同一个共享资源(Bean)进行读写,就出现线程不安全,问题:(脏读、数据串改)

会不会有线程安全问题: 会!
但是! 只要不在单例bean中声明一些共享的类成员变量(共享资源),并且不对共享资源进行读写, 也不会出现线程安全问题, 所以基本上bean就会使用默认的单例(节省内存开销)。

 单例

@Scope("singleton")
@Component
public class SingletonBean {// ...
}

原型

@Scope("prototype")
@Component
public class PrototypeBean {// ...
}

6.循环依赖

new applicationContext(); ----> new BeanA(); ——>解析@autowired----->去容器中获取BeanB(容器容器中没有B,创建B)----> ----> new BeanB(); ——>解析@autowired----->去容器中获取BeanA(容器容器中没有A,创建A)---->循环执行......

问题的根本Bean要经过依赖注入完(解析@autowired之后)后才会放到spring容器

解决

1.在配置文件中放开循环依赖的限制

# 放开循环依赖的限制#spring.main.allow-circular-references=true

2.代码设计层面:
        a. 把依赖的方法, 直接写在本类中,断绝其中一方依赖关系
        b. 添加一个中间类, 中间类去依赖A、B, 然后让中间类去组织他们的依赖方法。

3.延迟注入
        a.添加需要依赖的构造函数参数
        b.添加@Lazy注解

@Lazy
public BeanA(BeanB beanb) {this.beanb = beanb;
}@Lazy
public Bean(BeanA beana) {this.beana = beana;
}

四、SpringAOP面相切面编程

 AOP:Aspect Oriented Programming 面向切面编程 编程思想

4.1 为什么要用到AOP

所有业务功能都已经实现,但是最后我想在所有的功能里面加一个公共的功能,(记录所有的请求的用时), 利用AOP, 切面(需要增强的公共的、跟业务没有关系的公共代码)。可以在不改变原有业务代码的基础上进行了增强。
如何在Spring中创建一个所谓切面?
切面里面的代码怎么运行在业务方法(之前、之后)

4.2 AOP快速上手

第一步:引入pom.xml依赖

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>

 通过下面的图片我们可以看到AOP包中其实还有aspect,aspect是一个成熟的AOP框架

 

第二步:编写业务代码

package com.ltx.springtest.service;import org.springframework.stereotype.Service;@Service
public class UserService {//添加用户public void addUser(){System.out.println("添加用户");}//删除用户public void deleteUser(){System.out.println("删除用户");}//修改用户public void updateUser(){System.out.println("修改用户");}
}

第三步:编写aop切面类

之前说过AOP就是面向切面编程, OK大家现在可以直观的看到切面了,我们现在就是要面向这个切面类来编程,增强业务方法,记录日志:

package com.ltx.springtest;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LogAspect {/*** 切面环绕通知,针对UserService接口的所有方法执行进行监控。* 使用 ProceedingJoinPoint 参数来获取方法信息并控制方法的执行。* 该通知将在方法执行前、执行后以及发生异常时打印日志信息。** @param proceedingJoinPoint AOP联盟提供的 ProceedingJoinPoint 类型的参数,用于获取方法信息和继续方法的执行。* @return 返回方法的执行结果。* @throws Throwable 如果方法执行过程中抛出异常,则重新抛出异常。*/@Around("execution(* com.ltx.springtest.service.UserService.*(..))")public Object before(ProceedingJoinPoint proceedingJoinPoint){System.out.println("方法进入");Object proceed=null;try {proceed = proceedingJoinPoint.proceed();} catch (Throwable e) {System.out.println("方法异常");throw new RuntimeException(e);}finally {System.out.println("方法执行完毕");}System.out.println("方法返回");return proceed;}
}

第四步:测试

测试类

package com.ltx.springtest;import com.ltx.springtest.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class SpringTestApplicationTests {@Testvoid contextLoads(@Autowired UserService userService) {userService.addUser();}}

结果如下所示:

 

所以spring可以在不改变原有业务代码的基础上进行了增强
如何在Spring中创建一个所谓切面?

@Aspect+@Component+通知+切点

4.3 AOP详细使用

 4.3.1 @EnableAspectJAutoProxy

 启用AOP,没有这个注解AOP功能无法使用

@EnableAspectJAutoProxy是否一定要加?
为什么没有加AOP也起作用了?
SpringBoot其实会通过启动类自动帮我们加上@EnableAspectJAutoProxy,所以可以省略。
但是依然建议加上@EnableAspectJAutoProxy,在Spring中是要加的。

4.3.2 通知

 通知分类

后置通知@After:目标方法之后执行

异常通知@AfterThrowing:目标方法出现了异常执行
返回通知@AfterReturning:目标方法返回值执行
环绕通知@Around:可以把代码增强在目标方法的任意地方,更通用

前置通知实例

// 前置通知
@Before("execution(* com.example.c4_aop.advice.UserServce.*(..) )")
public void before(JoinPoint joinPoint){
// 记录当前方法的方法名,参数
String methodName = joinPoint.getSignature().getName();// 参数
Object[] args = joinPoint.getArgs();// 目标对象
Object target = joinPoint.getTarget();System.out.println("当前执行的方法是"+target.getClass()+"."+methodName+";参数"+ Arrays.toString(args));}

执行顺序:
正常:前置-->目标方法-->返回通知--->后置通知(finally)
异常: 前置-->目标方法-->异常通知--->后置通知(finally)

4.3.3 切点 

4.3.3.1 表达式抽取
@Pointcut("execution( public int cn.ltx.inter.MyCalculator.*(int,int))")public void myPoint(){}@Before("myPoint()")public static void start(JoinPoint joinPoint){Object[] args = joinPoint.getArgs();String name = joinPoint.getSignature().getName();System.out.println(name+"方法开始执行,参数是:"+ Arrays.asList(args));}@AfterReturning(value = "myPoint()",returning = "result")public static void stop(JoinPoint joinPoint,Object result){String name = joinPoint.getSignature().getName();System.out.println(name+"方法执行完成,结果是:"+result);}@AfterThrowing(value = "myPoint()",throwing = "exception")public static void logException(JoinPoint joinPoint,Exception exception){String name = joinPoint.getSignature().getName();System.out.println(name+"方法出现异常:"+exception.getMessage());}@After("myPoint()")private int end(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();System.out.println(name+"方法执行结束了......");return 0;}
}
4.3.3.2 切点表达式 

Spring AOP支持使用以下AspectJ切点标识符(PCD),用于切点表达式:
切点标识符:规定匹配的位置

  • execution: 用于匹配方法执行连接点。 这是使用Spring AOP时使用的主要切点标识符。 可以匹配到方法级别 ,细粒度

  • 访问修饰符:不写代表所有
  • 返回值:*代表所有
  • 完整限定名
      • com.xs.service
      • com.xs.*=com.xs.service com.xs.dao com.xs.xxx 名字任意,不代表层级任意
      • com.xs..= com.xs.service.imple 层级任意
      • *
      • com.xs..*=com.xs.service.imple.任意包. 任意类
      • 参数: 不写代表没有参数的方法, .. 代表任意参数 

五、Spring声明式事务

5.1 事务是什么

  一组关联的数据库操作 (转账);要么都成功,要么都失败,保证业务操作完整性的一种数据库机制。

ACID四大特性

A  原子性:原子性指的是 在一组业务操作下 要么都成功 要么都失败
在一组增删改查的业务下 要么都提交 要么都回滚
C  一致性:事务前后的数据要保证数据的一致性
在一组的查询业务下 必须要保证前后关联数据的一致性
I  隔离性:在并发情况下 事物之间要相互隔离。
D  持久性:数据一旦保存就是持久性的。

5.2 使用@Transactional注解

Spring的@Transactional注解是最常用的声明式事务管理方式。你可以将其添加到类或方法上,来声明事务的边界。

示例代码:

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;@Service
public class UserService {// 声明类级别的事务,类中的所有方法都会应用这个事务配置@Transactionalpublic void createUser(User user) {// 创建用户的业务逻辑}public void updateUser(User user) {// 更新用户的业务逻辑}// 声明方法级别的事务,只对这个方法生效@Transactional(readOnly = true)public User getUser(Long id) {// 获取用户的业务逻辑return user;}
}

5.3. 事务属性

@Transactional注解支持多个属性来定义事务的行为:

  • propagation:定义事务的传播行为,默认为Propagation.REQUIRED
  • isolation:定义事务的隔离级别,默认为Isolation.DEFAULT
  • timeout:定义事务的超时时间,默认为-1(不超时)。
  • readOnly:定义事务是否为只读,默认为false
  • rollbackFor:定义哪些异常会导致事务回滚,默认为Throwable
  • noRollbackFor:定义哪些异常不会导致事务回滚。

示例代码

@Transactional(readOnly = true, propagation = Propagation.SUPPORTS, rollbackFor = Exception.class)public User getUser(Long id) 
{ // 获取用户的业务逻辑 return user; 
}

5.4. 事务传播行为

事务的传播行为定义了当事务方法被另一个事务方法调用时,事务如何传播:

  • Propagation.REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
  • Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
  • Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
  • Propagation.REQUIRES_NEW:无论当前是否存在事务,都创建一个新的事务。
  • Propagation.NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
  • Propagation.NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。

示例代码

@Transactional(propagation = Propagation.REQUIRES_NEW) 
public void createUser(User user) 
{ // 创建用户的业务逻辑 
}

5.5. 事务隔离级别

事务的隔离级别定义了事务在执行过程中对数据的可见性:

  • Isolation.DEFAULT:使用后端数据库的默认隔离级别。
  • Isolation.READ_UNCOMMITTED:最低的隔离级别,允许读取未提交的数据。
  • Isolation.READ_COMMITTED:保证读取的都是已提交的数据。
  • Isolation.REPEATABLE_READ:保证在同一个事务中,多次读取同一数据的结果是一致的。
  • Isolation.SERIALIZABLE:最高的隔离级别,完全串行执行事务。

脏读(Dirty Read):一个事务读取到了另一个事务未提交的数据。如果那个事务最终回滚,读取到的数据将是无效的。

不可重复读(Non-repeatable Read):在一个事务中,多次读取同一数据集合时,由于其他事务的修改,可能会得到不同的结果。这违反了事务的隔离性。

幻读(Phantom Read):一个事务在执行过程中,由于其他事务的插入或删除操作,导致读取到之前不存在的行,或者丢失了之前存在的行。

丢失更新(Lost Update):两个或多个事务同时修改同一数据,其中一个事务的修改可能会覆盖另一个事务的修改。特别是当两个事务读取同一数据,然后各自修改并提交时

死锁(Deadlock):两个或多个事务相互等待对方持有的资源,导致无法继续执行。这通常发生在事务试图获取多个资源的锁时。

示例代码

@Transactional(isolation = Isolation.REPEATABLE_READ)
public void updateUser(User user) 
{ // 更新用户的业务逻辑 
}

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

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

相关文章

二、八、十、十六进制介绍及相互转换

目录 1、引言&#xff1a; 2、进制介绍及区分 2.1 介绍 2.2 区分 2.3 各进制的数字组成 3、2进制与10进制 3.1 十进制的介绍 3.2 二进制的介绍 4、2进制与10进制的转换 4.1 二进制转十进制 4.2 十进制转二进制 5、8进制和16进制 5.1 八进制的介绍 5.2 十六进制的介…

告别抠图烦恼,1秒搞定100张图片背景更换!

想象一下&#xff0c;你手头有几十张甚至上百张证件照需要从白底换成蓝底&#xff0c;而你只能用Photoshop一张张抠图&#xff0c;调整&#xff0c;然后保存。这个过程不仅耗时&#xff0c;还容易出错&#xff0c;特别是当你急需处理大量图片时&#xff0c;简直让人抓狂。 千鹿…

“云+端”体系覆盖590余所学校,张家口如何建设“教育一朵云”?

当将装有小苏打的气球套在装有白醋的塑料瓶瓶口时,一场令人惊叹的化学反应开始上演——瓶内瞬间白雾腾起弥漫,气泡翻滚不息,气球逐渐吹了起来......这是在张家口教育云平台上的由学生及家长上传的关于“小苏打吹气球”的科学实验视频,而学生们与家长参与的便是张家口市中小学云…

昇思MindSpore学习入门-静态图高级编程技巧二

如何优化执行性能 使用jit_class 使用场景&#xff1a;使用jit_class装饰器修饰自定义类&#xff0c;提高执行性能。jit_class应用于静态图模式&#xff0c;在动态图模式下&#xff0c;jit_class会被忽略&#xff0c;不影响动态图模式的执行逻辑。 jit_class的介绍 用户在网…

快递代拿系统/快递代领系统

摘 要 在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括快递代拿系统的网络应用&#xff0c;在外国快递代拿已经是很普遍的方式&#xff0c;不过国内的快递代拿可能还处于起步阶段。快递代拿系统具有代取物品功能。快递代拿系…

嵌入式学习Day12---C语言提升

目录 一、指针数组 1.1.什么是指针数组 2.2. 格式 2.3.存储 2.4.与字符型二维数组相比 2.5.什么时候使用指针数组 2.6.练习 二、数组指针 2.1.什么是数组指针 2.2.格式 2.3.一维数组 2.3.特点 2.4.什么时候使用 三、指针和数组的关系 3.1.一维数组和指针 …

ps制作镂空文字

1、创建文字。 2&#xff0c;栅格化文字 2、载入选取 3.选择》修改》收缩 4、然后再点击删除键&#xff0c;镂空文字效果就做好了。 同样适用于简单的图片logo

AI智能名片小程序在预测性产品管理与营销中的深度应用探索

摘要&#xff1a;本文深入探讨了AI智能名片小程序在预测性产品管理与营销中的广泛应用及其带来的深远影响。通过详细分析该技术在数据收集、市场分析、用户画像构建、个性化推荐、客户关系管理以及风险预测等方面的具体实践&#xff0c;本文揭示了AI智能名片小程序如何助力企业…

刚起步的小型海外仓有必要上WMS系统吗?答案来了

首先&#xff0c;这里的自动化主要是指将库存管理、SKU管理&#xff0c;一件代发、财务管理等海外仓的日常作业流程通过WMS系统实现的自动化。 而不是指海外仓自动化机器人、智能导轨等硬件设备。 文章会针对刚起步的一些小型海外仓是否有必要使用WMS系统进行讨论&#xff0c…

捷报来袭!上半年HCIE通过120人!证书量总计1767

智汇云校捷报 —上半年华为认证证书量1767本— 2024年上半年&#xff0c;云校HCIA、HCIP、HCIE证书量总计1767本&#xff01; HCIA&#xff1a;1240本 HCIP&#xff1a;407本 HCIE&#xff1a;120本 祝贺以下学员通过HCIE认证&#xff01; 欢迎有考证需求的学员 咨询云校…

Python文件打包exe文件

作者的一点话 你是否还在为py文件无法像其他可视化项目展示出来&#xff0c;制造图形界面的移动使用&#xff0c;那接下来我会与你一同使用它&#xff0c;并进行study&#xff0c;如有困惑&#xff0c;可随时联系。 然后&#xff0c;需要使用pysimplgui&#xff0c;如果…

[网络编程】网络编程的基础使用

系列文章目录 1、 初识网络 网络编程套接字 系列文章目录前言一、TCP和UDP协议的引入二、UDP网络编程1.Java中的UDP2.UDP回显代码案例3.UDP网络编程的注意事项 三、TCP网络编程1.TCP回显代码案例2.TCP多线程使用 总结 前言 在学习完基础的网络知识后&#xff0c;完成跨主机通…

元器件基础学习笔记——二极管基础

一、二极管基础 二极管是用半导体材料(硅、硒、锗等)制成的一种电子器件&#xff0c;具有单向导电性&#xff0c;是现代电子技术的基石。它在电子电路中扮演着至关重要的角色&#xff0c;通过与电阻、电容、电感等元器件的合理连接&#xff0c;能够实现整流、检波、限幅、稳压等…

Midjourney只需输入描述性文本,就能生成栩栩如生的图像

前言 Midjourney 是一款基于人工智能的图像生成工具&#xff0c;由 Midjourney 研究实验室开发。它最初在2022年3月面世&#xff0c;并在同年7月12日开始公开测试。Midjourney 的核心功能是能够根据用户提供的文本提示&#xff08;prompt&#xff09;&#xff0c;利用其内置的…

【软件测试】--接口自动化测试

1. 接口自动化 1.1 概念 接口测试&#xff1a;是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换、传递和控制管理过程&#xff0c;以及相互逻辑依赖关系 自动化测试&#xff1a;是把以人为驱动的测试行为转化为机器执行的一种过程 接口自动化测试&#xff1…

【详细】Ubuntu下安装qt5

Ubuntu下安装qt5 一. QT安装环境准备1、判断gcc是否安装2、安装g3、安装clang编译器4、安装 clang 5、安装make6、安装make-guile7、安装cmake 二. QT5安装1、安装Qt5的组件2、安装Qt的开发工具3、安装qtcreator4、安装qt55、安装qt charts&#xff08;可选&#xff09; 三、安…

国服最强文字转音频?Fish Speech

官网文档与示例 Fish Speech V1.2 是一款领先的文本到语音 (TTS) 模型&#xff0c;使用 30 万小时的英语、中文和日语音频数据进行训练。我尝试用1066运行&#xff0c;但是质量不尽如人意&#xff0c;建议使用RTX系列的显卡进行推理。 使用结果展示 text """20…

WPF项目实战视频《三》(主要为客户端软件界面设计)

20.WPF项目实战&#xff08;项目介绍&#xff09; 1.WEB API&#xff1a;接口&#xff0c;如何获取数据&#xff08;增删改查&#xff09; 2.客户端 项目功能&#xff1a; 待办&#xff0c;备忘录&#xff0c;汇总&#xff0c;完成比例&#xff0c;设置系统主题等。 21.WPF项…

nodejs与npm版本对应表

Node.js — Node.js 版本 (nodejs.org)

Springboot集成微信公众号模板通知java

先看效果 1、微信模板消息官方文档 微信公众平台 2、申请微信公众平台接口测试账号 微信公众平台 3、创建3个实体 &#xff08;1&#xff09;、ConfigBean import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configurat…