事件的力量:探索Spring框架中的事件处理机制

欢迎来到我的博客,代码的世界里,每一行都是一个故事


在这里插入图片描述

事件的力量:探索Spring框架中的事件处理机制

    • 前言
    • 什么是spring事件
    • 事件发布与监听
    • 自定义事件
    • 异步事件处理
    • 事件传播
    • 条件事件监听

前言

在现代应用程序中,各个组件之间的通信是至关重要的。想象一下,你的应用程序中的各个模块像是一个巨大的交响乐团,每个模块都是一位音乐家,而Spring事件机制就像是指挥家,将所有音乐家协调得天衣无缝。这种松耦合的通信方式使你的应用程序更加灵活、可维护,而且能够轻松应对变化。现在,让我们进入这个令人兴奋的音乐厅,探索Spring事件的世界。

什么是spring事件

在Spring框架中,事件(Events)是一种基本概念,用于实现松耦合的通信方式,允许不同组件之间进行相互通知和协作。Spring事件机制允许应用程序内的组件发送和接收事件,以便在系统中实现更松散的耦合,同时提高了可维护性和可扩展性。

以下是有关Spring事件的基本概念和工作原理:

1. 事件(Event):

  • 事件是一个对象,它封装了有关事件发生的信息。在Spring中,通常是一个普通的Java对象。
  • 事件可以包含任何有关事件的信息,例如事件类型、时间戳、发生事件的对象等。

2. 事件发布者(Event Publisher):

  • 事件发布者是一个组件,它负责发出事件。
  • 事件发布者将事件通知给已注册的事件监听器。

3. 事件监听器(Event Listener):

  • 事件监听器是接收和处理事件的组件。
  • 事件监听器订阅了特定类型的事件,并在事件发生时执行相应的操作。
  • 事件监听器是独立于事件发布者的,这意味着它们可以由不同的组件创建和管理,实现了松耦合。

4. Spring事件的工作原理:

  • 事件发布者将事件发布到Spring的应用程序上下文(ApplicationContext)。
  • 应用程序上下文将事件传递给所有已注册的事件监听器。
  • 事件监听器接收事件并执行相应的操作。

5. 使用场景:

  • Spring事件机制在各种场景下非常有用,包括:
    • 监听应用程序生命周期事件,如应用程序启动和关闭。
    • 监听领域对象的状态变化,例如数据库记录的更改。
    • 在分布式系统中实现事件驱动的通信。
    • 在模块之间进行解耦和通信。

6. 使用示例:

  • 示例代码如下,演示了如何使用Spring事件机制:
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class MyEventListener implements ApplicationListener<MyEvent> {

    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("Received MyEvent: " + event.getMessage());
    }

    @EventListener
    public void handleContextRefresh(ContextRefreshedEvent event) {
        System.out.println("Context is refreshed.");
    }

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        context.start();

        // 发布自定义事件
        context.publishEvent(new MyEvent("Hello, Spring Events!"));

        context.stop();
    }
}

class MyEvent extends ApplicationEvent {
    private final String message;

    public MyEvent(String message) {
        super(message);
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

在上述示例中,MyEventListener是一个事件监听器,它监听了自定义事件MyEvent。当MyEvent被发布时,监听器会接收并处理该事件。

总之,Spring事件是一种强大的松耦合通信机制,允许不同组件之间进行相互通知和协作,从而提高了应用程序的可扩展性和可维护性。

事件发布与监听

在Spring中,事件的发布和监听是通过Spring的ApplicationEventPublisher接口和事件监听器来实现的。以下是如何在Spring中发布事件以及如何编写事件监听器来处理这些事件的步骤:

1. 发布事件:

首先,您需要获取ApplicationEventPublisher对象,并使用它来发布事件。您可以在Spring组件(例如服务类、控制器、应用程序启动类等)中注入ApplicationEventPublisher

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void performSomeAction() {
        // 创建并发布自定义事件
        MyCustomEvent customEvent = new MyCustomEvent(this, "Some event data");
        eventPublisher.publishEvent(customEvent);
    }
}

2. 创建自定义事件:

您需要创建一个继承自ApplicationEvent的自定义事件类,并定义事件的数据。

import org.springframework.context.ApplicationEvent;

public class MyCustomEvent extends ApplicationEvent {
    private final String eventData;

    public MyCustomEvent(Object source, String eventData) {
        super(source);
        this.eventData = eventData;
    }

    public String getEventData() {
        return eventData;
    }
}

3. 编写事件监听器:

事件监听器是处理事件的组件。您可以编写一个类并实现ApplicationListener接口,然后在类上使用@Component或注册为Spring Bean。

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class MyEventListener implements ApplicationListener<MyCustomEvent> {
    @Override
    public void onApplicationEvent(MyCustomEvent event) {
        // 处理自定义事件
        String eventData = event.getEventData();
        System.out.println("Received custom event: " + eventData);
    }
}

4. 触发事件:

在需要触发事件的地方,调用发布事件的方法。

@Service
public class MyService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void performSomeAction() {
        // 创建并发布自定义事件
        MyCustomEvent customEvent = new MyCustomEvent(this, "Some event data");
        eventPublisher.publishEvent(customEvent);
    }
}

5. 启用事件处理:

确保Spring的组件扫描配置正确,以便Spring能够扫描和识别事件监听器。通常,@ComponentScan注解在主配置类上用于扫描包含事件监听器的包。

@SpringBootApplication
@ComponentScan(basePackages = "com.example")
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

6. 运行应用程序:

运行Spring应用程序,并在需要触发事件的地方调用相应的方法。事件监听器将会接收和处理事件。

public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);

        // 在应用程序中触发事件
        MyService myService = applicationContext.getBean(MyService.class);
        myService.performSomeAction();
    }
}

以上是在Spring中发布事件以及编写事件监听器的基本步骤。使用事件发布和监听机制,不同的组件可以在应用程序中实现松耦合的通信,使得应用程序更加灵活和可维护。

自定义事件

要创建自定义事件以满足应用程序的特定需求,您需要按照以下步骤进行操作:

1. 创建自定义事件类:

首先,您需要创建一个继承自org.springframework.context.ApplicationEvent的自定义事件类。这个类将包含您希望在应用程序中传递的事件信息。您可以在自定义事件类中添加任何属性和方法,以满足您的需求。

例如,假设您要创建一个名为UserRegistrationEvent的自定义事件,用于表示用户注册事件,可以这样定义事件类:

import org.springframework.context.ApplicationEvent;

public class UserRegistrationEvent extends ApplicationEvent {
    private final String username;

    public UserRegistrationEvent(Object source, String username) {
        super(source);
        this.username = username;
    }

    public String getUsername() {
        return username;
    }
}

在上述示例中,UserRegistrationEvent类包含了一个username属性,用于存储注册用户的用户名。

2. 发布自定义事件:

要发布自定义事件,您需要获取ApplicationEventPublisher对象并使用它来发布事件。这通常通过在需要发布事件的类中注入ApplicationEventPublisher来实现。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void registerUser(String username) {
        // 执行用户注册逻辑
        // ...

        // 发布自定义事件
        UserRegistrationEvent registrationEvent = new UserRegistrationEvent(this, username);
        eventPublisher.publishEvent(registrationEvent);
    }
}

在上述示例中,UserService类中的registerUser方法执行了用户注册逻辑,并在注册成功后发布了UserRegistrationEvent事件。

3. 创建事件监听器:

为了响应自定义事件,您需要创建一个事件监听器类,实现org.springframework.context.ApplicationListener接口,并在类中实现onApplicationEvent方法。

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class UserRegistrationListener implements ApplicationListener<UserRegistrationEvent> {
    @Override
    public void onApplicationEvent(UserRegistrationEvent event) {
        // 处理用户注册事件
        String username = event.getUsername();
        System.out.println("User registered: " + username);
    }
}

在上述示例中,UserRegistrationListener类监听UserRegistrationEvent事件,并在事件发生时执行相应的操作。

4. 注册事件监听器:

确保您的事件监听器被Spring识别和注册。通常,您可以通过将@Component@Service注解添加到监听器类上,或者在配置类中注册监听器。

5. 触发自定义事件:

在需要触发自定义事件的地方,调用相应的方法来发布事件。在上述示例中,我们在UserService类的registerUser方法中发布了UserRegistrationEvent事件。

6. 运行应用程序:

最后,运行Spring应用程序,并在适当的地方触发自定义事件。事件监听器将会接收并处理事件。

通过上述步骤,您可以创建自定义事件以满足应用程序的特定需求,并使用Spring的事件机制进行通信和协作。这种机制可以帮助您实现组件之间的松耦合,并提高应用程序的可扩展性和可维护性。

异步事件处理

在Spring中实现异步事件处理可以提高应用程序的性能和响应速度,特别是在处理耗时的操作时。Spring提供了异步事件处理的支持,您可以使用@Async注解和TaskExecutor来实现异步事件监听器。

以下是实现异步事件处理的步骤:

1. 添加异步支持配置:

首先,确保您的Spring应用程序启用了异步支持。在配置类上添加@EnableAsync注解,这会告诉Spring启用异步处理。

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;

@Configuration
@EnableAsync
public class AsyncConfig {
    // 其他配置
}

2. 创建异步事件监听器:

创建一个实现ApplicationListener接口的异步事件监听器。在需要异步处理的事件监听器方法上添加@Async注解。

import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class MyAsyncEventListener implements ApplicationListener<MyEvent> {

    @Async
    @Override
    public void onApplicationEvent(MyEvent event) {
        // 异步处理事件,可以是耗时的操作
        // ...
    }
}

在上面的示例中,@Async注解告诉Spring该方法应该在单独的线程中异步执行。

3. 发布事件:

在需要触发事件的地方,使用ApplicationEventPublisher发布事件,就像在同步事件处理中一样。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void performSomeAction() {
        // 执行操作

        // 发布事件,会异步处理
        MyEvent customEvent = new MyEvent(this, "Some event data");
        eventPublisher.publishEvent(customEvent);
    }
}

4. 配置异步执行器(可选):

如果需要更细粒度地配置异步执行器,可以定义一个TaskExecutor bean,并将其注入到Spring容器中。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;

@Configuration
public class AsyncConfig {

    @Bean
    public TaskExecutor taskExecutor() {
        return new SimpleAsyncTaskExecutor(); // 使用默认的异步执行器
    }
}

您可以根据需要使用不同的TaskExecutor实现,以满足应用程序的性能需求。

5. 运行应用程序:

最后,运行Spring应用程序,并在需要触发事件的地方调用相应的方法。事件监听器方法将会异步执行。

通过上述步骤,您可以实现在Spring中异步处理事件,从而提高应用程序的性能和响应速度。异步事件处理特别适用于处理可能导致阻塞的长时间运行任务,如发送电子邮件、生成报告等操作。请注意,在使用异步事件处理时,要谨慎处理线程安全和异常处理,以确保应用程序的稳定性。

事件传播

在Spring框架中,事件传播(Event Propagation)是指事件在应用程序中传递的机制。Spring提供了不同的事件传播机制,允许您控制事件在应用程序中的传递路径。事件传播机制定义了事件发布后如何传递给事件监听器,以及是否允许事件监听器干预事件的传递。

以下是有关事件传播机制的详细解释:

1. Spring中的事件传播类型:

Spring框架定义了几种不同的事件传播类型,用于控制事件的传递路径。以下是最常见的事件传播类型:

  • Publish (ApplicationEventPublisher.publishEvent(event)): 这是最常见的事件传播类型,事件会被直接传递给所有已注册的监听器。如果一个监听器抛出异常,它将中断事件传播,但不会影响其他监听器。

  • Publish Async (ApplicationEventPublisher.publishEvent(event) + 异步执行): 与Publish类似,但事件监听器会在异步线程中执行。这可以提高性能,但需要确保监听器是线程安全的。

  • Publish On Tx (ApplicationEventPublisher.publishEvent(event) + 事务内部): 事件只有在事务内部才会被传播。如果没有活动的事务,则事件将不会传播。这用于确保事件与事务一致性。

  • Publish On Tx Commit (ApplicationEventPublisher.publishEvent(event) + 事务提交后): 事件将在事务成功提交后才被传播。这用于确保事件在事务成功完成后才会被处理。

2. 控制事件传播类型:

您可以在发布事件时通过ApplicationEventPublisherpublishEvent(event)方法的重载来指定事件的传播类型。例如:

@Autowired
private ApplicationEventPublisher eventPublisher;

public void publishEvent(MyEvent event) {
    // Publish事件(默认传播类型)
    eventPublisher.publishEvent(event);

    // Publish Async事件
    eventPublisher.publishEvent(event, AsyncEventPublicationPolicy.ASYNC);

    // Publish On Tx事件
    eventPublisher.publishEvent(event, TransactionEventPublicationPolicy.PUBLISH_ON_TRANSACTION);

    // Publish On Tx Commit事件
    eventPublisher.publishEvent(event, TransactionEventPublicationPolicy.PUBLISH_AFTER_COMMIT);
}

通过使用不同的传播类型,您可以控制事件在应用程序中的传递路径。例如,如果希望事件在事务内部处理,可以使用Publish On Tx传播类型。

3. 事件监听器的顺序:

事件监听器的注册顺序也影响事件的传播路径。Spring允许您通过@Order注解或Ordered接口来控制事件监听器的执行顺序。可以通过设置@Order注解中的值或实现Ordered接口中的getOrder方法来指定监听器的执行顺序。

@Component
@Order(1) // 设置监听器的执行顺序
public class MyEventListener1 implements ApplicationListener<MyEvent> {
    // ...
}

@Component
@Order(2)
public class MyEventListener2 implements ApplicationListener<MyEvent> {
    // ...
}

通过设置@Order或实现Ordered接口,您可以确保事件监听器按照指定的顺序执行。

总之,Spring的事件传播机制允许您在应用程序中控制事件的传递路径,以及事件监听器的执行顺序。通过选择合适的事件传播类型和设置监听器的执行顺序,您可以实现更精确的事件处理逻辑,以满足应用程序的需求。这种机制有助于实现松耦合的组件通信和更高的灵活性。

条件事件监听

在Spring中,您可以使用条件事件监听器来根据条件来选择性地监听事件,以实现更灵活的事件处理。条件事件监听器允许您在监听事件之前进行条件检查,仅在条件满足时才执行监听器的操作。

以下是如何实现条件事件监听器的步骤:

1. 创建条件事件监听器:

首先,您需要创建一个事件监听器类,实现ApplicationListener接口。然后,您可以在监听器类中编写条件逻辑来控制何时执行事件监听器的操作。

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

@Component
public class ConditionalEventListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        // 检查条件是否满足
        if (conditionIsMet(event)) {
            // 执行事件处理逻辑
            // ...
        }
    }

    private boolean conditionIsMet(MyEvent event) {
        // 根据事件和其他条件来判断是否满足条件
        // 返回true表示满足条件,返回false表示不满足条件
        // 例如,可以检查事件中的数据或应用程序的状态等条件
        return event.getData() != null;
    }
}

在上面的示例中,ConditionalEventListener类的onApplicationEvent方法会首先检查条件是否满足,然后在条件满足时执行事件处理逻辑。

2. 发布事件:

在需要触发事件的地方,使用ApplicationEventPublisher发布事件,就像在常规事件处理中一样。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void performSomeAction() {
        // 执行操作

        // 发布事件
        MyEvent customEvent = new MyEvent(this, "Some event data");
        eventPublisher.publishEvent(customEvent);
    }
}

3. 运行应用程序:

最后,运行Spring应用程序,并在需要触发事件的地方调用相应的方法。条件事件监听器会在条件满足时执行。

public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);

        // 在应用程序中触发事件
        MyService myService = applicationContext.getBean(MyService.class);
        myService.performSomeAction();
    }
}

通过上述步骤,您可以实现条件事件监听,根据特定条件来选择性地执行事件监听器的操作。这允许您在事件处理中引入更多的灵活性和控制,以满足应用程序的需求。条件事件监听器可以帮助您根据不同的条件采取不同的处理方式,实现更多定制化的事件处理逻辑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

储氢材料行业调研:市场需求将不断增长

近年来&#xff0c;热度持续升温的碳中和、碳达峰话题&#xff0c;使得氢能及其相关产业被高度关注&#xff0c;而决定氢能应用关键的是安全、高效的氢能储运技术。在氢能需求不断增长的情况下&#xff0c;储氢材料行业是市场也将不断发展。在氢能需求不断增长的情况下,储氢材料…

《Python 网络爬虫简易速速上手小册》第4章:Python 网络爬虫数据抓取技术(2024 最新版)

文章目录 4.1 解析 HTML 与 CSS4.1.1 重点基础知识讲解4.1.2 重点案例&#xff1a;使用 BeautifulSoup 解析博客文章4.1.3 拓展案例 1&#xff1a;使用 lxml 和 XPath 解析产品信息4.1.4 拓展案例 2&#xff1a;动态加载内容的抓取挑战 4.2 动态内容抓取技术4.2.1 重点基础知识…

【C++】内存管理深入解析

目录 1. 内存的五大区域1.1 栈区&#xff08;Stack&#xff09;1.2 堆区&#xff08;Heap&#xff09;1.3 全局/静态存储区1.4 常量存储区1.5 代码区 2. 回顾c语言的动态内存管理2.1 malloc/calloc/realloc2.2 free 3. C中的新旧对话3.1 new3.2 delete 4. new/delete的实现原理…

ES6 ~ ES11 学习笔记

课程地址 ES6 let let 不能重复声明变量&#xff08;var 可以&#xff09; let a; let b, c, d; let e 100; let f 521, g "atguigu", h [];let 具有块级作用域&#xff0c;内层变量外层无法访问 let 不存在变量提升&#xff08;运行前收集变量和函数&#…

ZigBee学习——在官方例程上实现串口通信

Z-Stack版本为3.0.2 IAR版本为10.10.1 文章目录 一、添加头文件二、定义接收缓冲区三、编写Uart初始化函数四、编写串口回调函数五、函数声明六、函数调用七、可能遇到的问题(function “halUartInit“ has no prototype) 以下所有操作都是在APP层进行&#xff0c;也就是这个文…

[Python 安装]

进入Python的官方下载页面 http://www.python.org/download/ 然后进行软件的下载 下载好之后点击exe会出现安装界面&#xff0c;接着进行安装&#xff0c;选择安装路径。 运行Python 安装成功后&#xff0c;打开命令提示符窗口&#xff08;winR,在输入cmd回车&#xf…

C程序训练:二分查找法的应用之2

本文来自&#xff1a;C程序训练&#xff1a;二分查找法的应用之2 在《C程序训练&#xff1a;二分查找法的应用》一文中介绍了利用二分查找计算某个区间中数的个数&#xff0c;本文介绍利用二分查找法计算数列中出现单个数字的位置。题目描述如下。 题目描述&#xff1a;一维整…

Python进阶--下载想要的格言(基于格言网的Python爬虫程序)

注&#xff1a;由于上篇帖子&#xff08;Python进阶--爬取下载人生格言(基于格言网的Python3爬虫)-CSDN博客&#xff09;篇幅长度的限制&#xff0c;此篇帖子对上篇做一个拓展延伸。 目录 一、爬取格言网中想要内容的url 1、找到想要的内容 2、抓包分析&#xff0c;找到想…

Netty源码系列 之 bind绑定流程 源码

Netty框架总览 Netty是一个基于NIO异步通信框架 Netty框架是由许多组件&#xff0c;优化的数据结构所构建成。 正是通过灵活的组件构建&#xff0c;优化后的数据结构&#xff0c;进而才能保证Netty框架面对高并发场景具有一定的能力 Netty相关组件 Netty重要的组件有&…

代码随想录算法训练营DAY14 | 二叉树 (1)

一、二叉树理论基础 1.存储方式 链式存储&#xff1a; 顺序存储&#xff1a; 2.二叉树标准定义(Java) public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {…

spring cloud stream

背景 主要解决不同消息中间件切换问题。实现不同中间件的代码解耦。 链接: 支持的中间件 后文使用kafka测试。 引入依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-stream</artifactId></depende…

微服务介绍、使用 Nacos 实现远程调用以及 OpenFeign 的使用

1 微服务的概念 区别于单体项目 单体项目拆分成微服务项目的目标&#xff1a;高内聚、低耦合 拆分思路 纵向拆分&#xff1a;根据功能模块 横向拆分&#xff1a;抽取可复用模块 2 微服务拆分——远程调用 背景&#xff1a;微服务单一职责&#xff0c;每个服务只有自己的功能…

电脑没有声音是怎么回事?几招快速解决

当电脑突然失去声音&#xff0c;这可能成为一种令人烦恼的体验&#xff0c;尤其是在你期望享受音乐、观看视频或进行在线会议的时候。幸运的是&#xff0c;大多数时候&#xff0c;电脑没有声音的问题是可以迅速解决的。电脑没有声音是怎么回事&#xff1f;本文将为你介绍一些常…

老是抓不准现货白银实时报价怎么办?

现货白银的实时报价是不断变动的&#xff0c;投资者要了解当下的现货白银实时走势&#xff0c;并且依靠对实时报价的分析预判未来的趋势&#xff0c;这是不容易的&#xff0c;但是不是不能做到呢&#xff1f;也不是。因为市场不是横盘就是趋势&#xff0c;只要有趋势&#xff0…

零代码3D可视化快速开发平台

老子云平台 老子云3D可视化快速开发平台&#xff0c;集云压缩、云烘焙、云存储云展示于一体&#xff0c;使3D模型资源自动输出至移动端PC端、Web端&#xff0c;能在多设备、全平台进行展示和交互&#xff0c;是全球领先、自主可控的自动化3D云引擎。此技术已经在全球申请了专利…

.NET Avalonia开源、免费的桌面UI库 - SukiUI

前言 今天分享一款.NET Avalonia基于MIT License协议开源、免费的桌面UI库&#xff1a;SukiUI。 Avalonia介绍 Avalonia是一个强大的框架&#xff0c;使开发人员能够使用.NET创建跨平台应用程序。它使用自己的渲染引擎绘制UI控件&#xff0c;确保在Windows、macOS、Linux、An…

用云手机打造tiktok账号需要注意些什么?

随着tiktok平台的火热&#xff0c;越来越多的商家开始尝试更高效的tiktok运营方法。其中&#xff0c;tiktok云手机作为一种新科技引起了很多人的注意&#xff0c;那么用云手机运营tiktok需要注意些什么&#xff1f;下文将对此进行详细解析。 1. 不是所有的云手机都适合做tiktok…

跳过mysql密码并重置密码 shell脚本

脚本 目前只是验证了5.7 版本是可以的&#xff0c;8.多的还需要验证 以下是一个简单的Shell脚本&#xff0c;用于跳过MySQL密码设置并重置密码&#xff1a; #!/bin/bash yum install psmisc -y# 停止MySQL服务 sudo service mysqld stop# 跳过密码验证 sudo mysqld --skip-g…

通过 docker-compose 部署 Flink

概要 通过 docker-compose 以 Session Mode 部署 flink 前置依赖 Docker、docker-composeflink 客户端docker-compose.yml version: "2.2" services:jobmanager:image: flink:1.17.2ports:- "8081:8081"command: jobmanagervolumes:- ${PWD}/checkpoin…

分析伦敦银报价总失败?你试试这样

做伦敦银交易的投资者要先对伦敦银报价进行分析&#xff0c;但是有些投资者反映自己分析伦敦银报价总是失败&#xff0c;抓不住市场价格的变化趋势&#xff0c;为什么会这样呢&#xff1f;我们可以从以下这两个方面来考虑。 转变分析工具。为什么分析伦敦银报价总失败&#xff…