当前位置: 首页 > news >正文

SpringBoot的事务/调度/缓存/邮件发送和一些Spring知识点总结

目录

1、SpringBoot的事务管理

2、SpringBoot的异步任务

3、SpringBoot定时任务调度

4、SpringBoot整合Mail发送邮件

5、Spring框架中的Bean的作用域

6、Spring框架中的Bean的线程安全

7、 Spring框架中的Bean生命周期

8、Spring框架如何解决循环依赖?

9、Spring框架中有哪些注解?

10、Spring框架中用到的设计模式


1、SpringBoot的事务管理

        在mybatis中,我们还要创建一个动态代理来处理业务中的事务,但是SpringBoot提供了注解的方式快速的实现了事务的相关逻辑。

        如果我们现在有一个方法是批量创建多个Consume对象,创建了一个bathAdd()方法,方法中如果出现了一个异常代码片段,没有事务的情况下前面的对象会被新增在数据库中,后面的则不会执行新增。这样的逻辑是不对的,所以我们在这个方法前面加上@Transaction的注解。

Service层代码: 

@Service
public class CustomerServiceImp extends ServiceImpl<ConsumeMapper, Consumer> implements ICustomerService{@Resourceprivate ConsumeMapper dao;@Transactional@Overridepublic void batchAdd() {dao.insert(new Consumer(7,"牛",new Date(),"男"));int a = 10/0;dao.insert(new Consumer(8,"牛1",new Date(),"男"));dao.insert(new Consumer(9,"牛2",new Date(),"男"));}}

         @Transactional:表示这个方法中的所有数据库操作将在一个事务中执行。如果在方法执行过程中抛出异常,事务将会回滚。

        @Resource 

        private ConsumeMapper dao;

         表示注入了一个名为dao的ConsumeMapper对象,用于执行数据库操作。

controller层代码:

@RestController
public class ConsumerControllerImp {@Autowiredprivate ICustomerService service;@RequestMapping("/add")public String batchAdd() {service.batchAdd();return "成功";}
}

         @RestController:标记这个类是一个Spring MVC控制器,并且返回的内容会直接作为HTTP响应的Body(通常是JSON格式)。相比于@Controller,@RestController省去了额外的@ResponseBody注解。

        通过controller层调用方法batchAdd()是调用service层的batchAdd()。

测试类主入口:

@SpringBootApplication
@EnableTransactionManagement
public class Springboot01CenterTxApplication {public static void main(String[] args) {SpringApplication.run(Springboot01CenterTxApplication.class, args);}}

         @EnableTransactionManagement:启用Spring的注解驱动的事务管理功能。它使得Spring能够识别和处理类或方法上的@Transactional注解,从而管理事务边界,对有@Transactional的方法或类进行事务管理。

2、SpringBoot的异步任务

        在项目开发中,绝大多数情况下都是通过同步方式处理业务逻辑的,但是比如批量处理数据,批量发送邮件,批量发送短信等操作容易造成阻塞的情况,之前大部分都是使用多线程来完成此类任务,而在 Spring 3+之后,就已经内置了@Async注解来完美解决这个问题,从而提高效率。

        异步执行核心概念是任务在不同线程中执行,而不是在同一个线程中按照顺序执行。具体来说,异步执行允许任务几乎同时进行,但它们是在不同线程中并行处理的,,而不是像同步执行那样在同一个线程中按顺序完成。

        从controller层调用方法batchAdd()到service层:

service层代码:

@Service
public class CustomerServiceImp implements ICustomerService{@Override@Asyncpublic void batchAdd() {try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("======>批量新增");}
}

         @Async:这是Spring提供的异步处理注解。标记在方法上时,该方法将在单独的线程中异步执行,不会阻塞调用者线程。使用这个注解的前提是需要在配置类或启动类中启用异步功能,例如通过@EnableAsync来实现。

        Thread.sleep(3000);: 这行代码让当前线程休眠3秒钟,模拟批量添加操作的延迟。

测试类主入口:

@SpringBootApplication
@EnableAsync // 开启异步处理
public class Springboot04CenterAysncApplication {public static void main(String[] args) {SpringApplication.run(Springboot04CenterAysncApplication.class, args);}}

        @EnableAsync:当你在启动类中使用了@EnableAsync时,Spring会扫描整个应用程序,识别并处理所有标记了@Async注解的方法。标记了@Async的方法会在一个单独的线程池异步执行,而不是在主线程中执行。这使得主线程不会被这些方法阻塞,从而可以继续处理其他任务。

3、SpringBoot定时任务调度

        SpringTask:在项目开发中,经常需要执行一些定时任务,比如每月1号凌晨需要汇总上个月的数据分析报表;每天凌晨分析前一天的日志信息等定时操作。Spring 为我们提供了异步执行定时任务调度的方式。

        就比如我想要每隔4秒给我发送一个提醒:

之间创建一个MyJob类:

@Component
public class MyJob {//秒 分 时 日 月 星期 年// 从3秒开始每隔4秒执行一次@Scheduled(cron = "3/4 00 22 15 8 ?")public void show(){System.out.println("陕西发布暴雪蓝色预警");}
}

         @Scheduled标识的方法会进行定时处理,需要通过 cron 属性来指定 cron 表达式:秒 分 时 日 月 星期 年。

        在上面的代码中,‘3/4’代表从第三秒开始,每个寺庙执行一次。'00'代表在 0 分钟时执行。其他的就是对应的时、日、月星期执行,一般不加年,加年会报错。

        总体可理解为:在8月15号的22点00分第三秒的时候开始执行,每隔4秒执行一次。

测试类主入口:

@SpringBootApplication
@EnableScheduling // 开启任务调度
public class Springboot03CenterJobApplication {public static void main(String[] args) {SpringApplication.run(Springboot03CenterJobApplication.class, args);}}

        其中@EnableScheduling用于启用 Spring 的定时任务执行功能。当你在配置类上使用 @EnableScheduling 注解时,Spring 会扫描并识别使用了 @Scheduled 注解的方法,并按照指定的时间间隔或时间点执行这些方法。

4、SpringBoot整合Mail发送邮件

首先添加坐标:

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

其次是配置yml信息,用来配置你的发送邮箱。

spring:mail:password: 邮箱授权码username: 邮箱账号,不用加后缀host: smtp.qq.com (邮箱类型)properties:smtp:ssl:enable: true

         最后是在测试类中去完成方法并测试:

        首先是简单的发送邮件,只有文字发送:

    @Autowired(required = false)private JavaMailSenderImpl javaMailSender;//发送简单邮件@Testvoid show1() {//1.创建邮件对象SimpleMailMessage simpleMailMessage = new SimpleMailMessage();//2.设置信息simpleMailMessage.setSubject("疫情全面放开");simpleMailMessage.setText("2022年好难,做了11个月的核酸,结果在第12个月阳了~~~");simpleMailMessage.setFrom("?@qq.com");simpleMailMessage.setTo("?@qq.com");//3.发送邮件javaMailSender.send(simpleMailMessage);System.out.println("发送成功~~~");}

          这里面首先用使用 SimpleMailMessage 类创建一个简单的邮件对象。

  •         setSubject("疫情全面放开"):设置邮件的主题为 "疫情全面放开"。
  •         setText("2022年好难,做了11个月的核酸,结果在第12个月阳了~~~"):设置邮件的正文内容。
  •         setFrom("?@qq.com"):设置发件人地址。
  •         setTo("?@qq.com"):设置收件人地址。

           其次是发送复杂邮件,就比如带张照片等等操作均是复杂发送:

@Testvoid show2()throws Exception {//1.创建邮件对象MimeMessage mimeMessage = javaMailSender.createMimeMessage();//2.创建MimeMessageHelperMimeMessageHelper mimeMessageHelper =  new MimeMessageHelper(mimeMessage,true);//3.设置信息mimeMessageHelper.setSubject("程序员的误解");mimeMessageHelper.setText("程序员是个<span style='color:red'>高薪,高危</span>的职业",true);mimeMessageHelper.addAttachment("1.jpg",new File("?.jpg"));mimeMessageHelper.setFrom("?4@qq.com");mimeMessageHelper.setTo("?@qq.com");//4.发送邮件javaMailSender.send(mimeMessage);}

        其他的跟上面的代码一致,新增了一个addAttachment()方法,第一个参数为附件在邮件中显示的文件名,收件人下载附件时,看到的文件名将是这个参数指定的名称。第二个参数为这是一个 File 对象,表示需要附加到邮件中的实际文件。它可以是本地存储在文件系统中的任何文件。

5、Spring框架中的Bean的作用域

        singleton:Spring只会为该bean对象只会创建唯一实例Spring中的bean默认都是单例:
        prototype:每次获取bean,Spring会创建一个新的bean实例;
        request:每一次HTTP请求,Spring会创建一个新的bean实例;
        session:不同的HTTP会话,Spring会创建不同的bean实例;

        通过XML方式设置bean的作用域:

<bean id="demoDaoBean" class="com.apesource.dao.DemoDAOImpl" scope="singleton"/> 

         通过注解方式设置bean的作用域:

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoDAOImpl implements IDemoDAO{ }
6、Spring框架中的Bean的线程安全

        对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。

        对于singleton作用域的Bean,所有的线程都共享一个单例状态的Bean,存在资源竞争,因此是存在线程安全问题的。

        解决办法:对于singleton作用域的单例bean ,它的线程安全问题,常见有两种解决办法:

  • 在bean中尽量避免定义可变的成员变量(用于保存数据的成员变量);
  • 在类中定义一个ThreadLocal 成员变量,将需要可变的成员变量保存 ThreadLocal 中;
7、 Spring框架中的Bean生命周期

        Spring Bean的生命周期总体分四个阶段实例化=>属性注入=>初始化=>销毁。

        Step1 实例化Bean:根据配置文件中Bean 的定义,利用| Java Reflection 反射技术创建Bean的实例。

        Step2 注入对象依赖的属性值(或对象)。

        Step3 处理各种Aware接口:Spring会检测该Bean 是否实现了xxxAware 接口,通过Aware类型的接口,可以让Spring框架为当前 Bean 注入相应的内容

  • 如果Bean实现BeanNameAware接口,会调用它实现的setBeanName(String beanId)方法,注入Bean的名字;
  • 如果Bean实现BeanClassLoaderAware 接口,调用setBeanClassLoader()方法,注入ClassLoader对象的实例;
  • 如果Bean实现BeanFactoryAware接口,会调用它实现的setBeanFactory()方法,注入的是Spring工厂;
  • 如果Bean实现ApplicationContextAware接口,会调用setApplicationContext()方法,注入Spring上下文;

        Step4 执行BeanPostProcessor前置处理:如果想对Bean进行一-些自定义的前置处理, 那么可以让Bean实现了BeanPostProcessor 接口,将会在该阶段调用postProcessBeforeInitialization(0bject obj,String s)方法。

        Step5 执行InitializingBean初始化方法:如果 Bean 实现了InitializingBean接口,执行afeterPropertiesSet()方法。

        Step6 执行init-method自定义初始化方法:如果 Bean在Spring配置文件中配置了init-method属性,则会自动调用其配置的初始化方法。

        Step7 执行BeanPostProcessor后置处理:如果这个Bean 实现了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法,由于这个方法是在Bean初始化结束后调用;

        以上几个步骤完成后, Bean已经被正确创建,可以正常使用这个Bean了。

        Step8 执行DisposableBean销毁Bean:当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean 这个接口,会调用其实现的destroy() 方法执行销毁;

        Step9 执行destroy-method自定义销毁方法:如果这个Bean的Spring配置中配置了destroy
-method属性,会自动调用其配置的自定义销毁方法。

8、Spring框架如何解决循环依赖?

        循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题;

9、Spring框架中有哪些注解?

        用于声明Bean的注解:

  • @Component:定义通用Bean的注解,可标注任意类为Bean。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注。
  • @Repository:定义数据访问层Bean的注解。
  • @Service:定义业务层Bean的注解。
  • @Controller:定义控制器Bean的注解。

        用于注入的注解: 

  • @Autowired:按类型自动注入
  • @Qualifier:按名称自动注入

         声明配置、扫描、启用特性的注解:

  • @Configuration:声明配置类
  • @ComponentScan:组件扫描
  • @EnableScheduling:启用任务调度
  • @EnableAspectJAutoProxy:启用自动代理工厂
10、Spring框架中用到的设计模式
  • 工厂模式:Spring 使用工厂模式,通过BeanFactory 或Applicat ionContext来创建对象;
  • 单例模式:Bean 默认作用域为单例,按照单例设计模式进行设计实现;
  • 策略模式:Resource 的实现类,针对不同的资源文件,实现了不同方式的资源获取策略;
  • 代理模式:Spring的AOP的实现依靠动态代理(JDK的反射和CGLIB);
  • 模板方法:Spring提供了JdbcTemplate,RedisTemplate 等模板对象,将相同的操作步骤进行了封装;
  • 适配器模式:Spring AOP的增强或通知( Advice )使用到了适配器模式, Spring MVC中也用到了适配器模式适配Controller;

相关文章:

SpringBoot的事务/调度/缓存/邮件发送和一些Spring知识点总结

目录 1、SpringBoot的事务管理 2、SpringBoot的异步任务 3、SpringBoot定时任务调度 4、SpringBoot整合Mail发送邮件 5、Spring框架中的Bean的作用域 6、Spring框架中的Bean的线程安全 7、 Spring框架中的Bean生命周期 8、Spring框架如何解决循环依赖&#xff1f; 9、…...

透明加密技术

透明加密技术&#xff0c;也被称为透明数据加密&#xff08;Transparent Data Encryption, TDE&#xff09;&#xff0c;是一种加密方法&#xff0c;它允许数据在存储时自动加密和解密&#xff0c;而不需要用户进行任何手动操作。透明加密技术主要应用于数据库、文件系统和磁盘…...

深入理解Faiss:高效向量检索的利器

近年来&#xff0c;随着人工智能和机器学习技术的飞速发展&#xff0c;向量检索技术变得越来越重要。无论是在推荐系统、图像搜索还是自然语言处理等领域&#xff0c;向量检索都扮演着至关重要的角色。而在众多向量检索库中&#xff0c;Faiss&#xff08;Facebook AI Similarit…...

RK3576 芯片介绍

RK3576 芯片介绍 RK3576瑞芯微第二代8nm高性能AIOT平台&#xff0c;它集成了独立的6TOPS&#xff08;Tera Operations Per Second&#xff0c;每秒万亿次操作&#xff09;NPU&#xff08;神经网络处理单元&#xff09;&#xff0c;用于处理人工智能相关的任务。此外&#xff0…...

Python模块篇(五)

模块 模块与包模块的导入与使用标准库的常用模块第三方库的安装与使用&#xff08;如&#xff1a;pip工具&#xff09; 模块与包 模块是一个包含 Python 代码的文件&#xff0c;通常以 .py 作为扩展名。一个模块可以包含函数、类、变量&#xff0c;以及可执行的代码段。模块的…...

西安旅游系统--论文pf

TOC springboot383西安旅游系统--论文pf 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现&#xff0c;改变了几千年以来人们的生活&#xff0c;不仅仅是生活物资的丰富&#xff0c;还有精神层次的丰富。在互联网诞生之前&#xff0c;地域位置往往是人们思想上不可跨域的鸿…...

分享一个思路,使用插桩技术解决慢查询测试问题

前段时间&#xff0c;我负责测试的系统在生产环境运行出现问题。该系统对于响应时间要求较高&#xff0c;问题发生的时候并发很高&#xff0c;出现大量请求超时&#xff0c;超时请求比例随时间推迟越来越高&#xff0c;最后几乎全部请求都失败。滚动重启了所有进程后&#xff0…...

【STM32项目】在FreeRtos背景下的实战项目的实现过程(二)

个人主页~ 实战项目的实现过程&#xff08;一&#xff09;~ 实战项目的实现过程 二、初步了解各个外设硬件1、OLED模块2、GPS模块3、MPU6050模块4、超声测距模块5、温度测控模块6、语音模块7、SIM模块8、按键模块 三、查阅资料1、查看手册2、查找例程 四、研究硬件功能1、OLED…...

javaer快速入门 goweb框架 gin

gin 入门 前置条件 安装环境 配置代理 # 配置 GOPROXY 环境变量&#xff0c;以下三选一# 1. 七牛 CDN go env -w GOPROXYhttps://goproxy.cn,direct# 2. 阿里云 go env -w GOPROXYhttps://mirrors.aliyun.com/goproxy/,direct# 3. 官方 go env -w GOPROXYhttps://goproxy.…...

SQL - 数据类型

字符串类型 char(10)&#xff0c;存储固定长度字符串 varchar(255)&#xff0c;存储可变长度字符串 mediumtext&#xff0c;中文本&#xff0c;对于存储JSON对象、SCV字符串很好使 longtext&#xff0c;长文本&#xff0c;可以很好地存储教本或许多年地日志文件 tinytext&#…...

进程相关知识

进程和程序的区别 程序 程序是静态的&#xff0c;是存储在硬盘、SSD等存储介质中的一个文件&#xff0c;通常由源代码&#xff08;如 .c 文件&#xff09;编译生成的二进制可执行文件&#xff08;如 a.out&#xff09;。程序包含了指令和数据&#xff0c;但在未被执行时&#…...

萝卜快跑和端到端的自动驾驶(1)

先看一篇论文 2311.18636 (arxiv.org) 这篇论文里有一个非常好的图 比较了一下模块化任务(级联任务)和端到端自动驾驶的区别 首先什么叫模块化任务(级联) 如上图所示&#xff0c;左边的方块中的子方块&#xff0c;是展示了自动驾驶获取数据的途径&#xff0c;这里包括&…...

通信原理学习笔记

一个手机通话需要经过下面三个网络 类别接入网&#xff08;Access Network&#xff09;承载网&#xff08;Transport Network&#xff09;核心网&#xff08;Core Network&#xff09;定义连接终端用户与电信网络的部分。在接入网和核心网之间传输数据的网络。处理、交换和管理…...

系统编程---day4

1. 链接文件 命令行&#xff1a; ln -s 文件名 softlink 1.1 symlink int symlink(const char *oldpath, const char *newpath); 功能:创建一个链接向oldpath文件的新符号链接文件 参数:oldpath:被链接向的文件的路径 newpath:新符号链接文件 返回值:成功返回0,失败返回…...

01:电容的什么,各类电容的优缺点

1.电容是什么&#xff1f; 电容是由两块不连通的导体&#xff0c;已经中间的不导电材料组成 电容结构&#xff1a; 1.2电容的容量计算公式 C ε s d \displaystyle\frac{εs}{d} dεs​ 1.3常见电容的种类 1.4各类电容的特点...

Android+Jacoco+code-diff全量、增量覆盖率生成实战

背景 主要是记录下Android项目使用jacoco生成代码覆盖率的实战流程&#xff0c;目前已完成全量覆盖方案&#xff0c;仅使用jacoco就能实现&#xff1b; 由于我们的Android端是使用Java和kotlin语言,目前增量的方案code-diff仅针对Java代码&#xff0c;卡在kotlin文件的分析&am…...

乌龟对对碰在线版

爆肝两天使用vue开发了一个在线版的乌龟对对碰小游戏之幸运对对碰。没有找到合适的乌龟素材&#xff0c;现在使用小兔子代替。 体验地址&#xff1a;幸运对对碰 | 乌龟对对碰小游戏 之前的python版本的乌龟对对碰&#xff1a;写文章-CSDN博客 乌龟对对碰-幸运对对碰...

如何更改select option边框颜色和选中的颜色

<!doctype html> <html> <head> <meta charset"utf-8"> <title>如何更改select option边框颜色和选中的颜色</title> </head><style>ul{border: 1px solid #000000;width: 500px;height: auto;background-color: aq…...

6. 数据结构—串的匹配算法

1.BF算法(暴力算法) //模式匹配(暴力算法) int Index(SString S,SString T){int i1,j1;while(i<S.length&&j<T.length){if(S[i]T[i]){i;j;}else{ii-j2; //最开始匹配的位置的后一个j1; //从头匹配 }}if(j>T.length)return i-T.length;return return 0…...

九大服务架构性能优化方式

来源&#xff1a;九大服务架构性能优化方式 目录 性能优化九大方式&#xff1a; 缓存 使用什么样的缓存 缓存常见问题 缓存淘汰 缓存数据一致性 并行化处理 批量化处理 数据压缩合并 无锁化 顺序写 分片化 避免请求 池化 异步处理 总结 最近做了一些服务性能优…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验

Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中&#xff0c;API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关&#xff0c;Kong凭借其插件化架构…...

C# winform教程(二)----checkbox

一、作用 提供一个用户选择或者不选的状态&#xff0c;这是一个可以多选的控件。 二、属性 其实功能大差不差&#xff0c;除了特殊的几个外&#xff0c;与button基本相同&#xff0c;所有说几个独有的 checkbox属性 名称内容含义appearance控件外观可以变成按钮形状checkali…...