前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【开发者成长激励计划-基于TencentOS Tiny的非侵入式86型智能开关】

【开发者成长激励计划-基于TencentOS Tiny的非侵入式86型智能开关】

原创
作者头像
繁林
修改于 2022-08-10 01:51:54
修改于 2022-08-10 01:51:54
1.1K10
代码可运行
举报
运行总次数:0
代码可运行

非侵入式86型智能开关产品.pptx

1 产品介绍

非侵入式86型智能开关装置是针对遵循86型安装盒(JB/T 8593-2013)的开关面板简易接入物联网的一款辅助装置. 它能在用户不改动原有正常的86型开关面板的情况下, 实现对开关面板接入到物联网, 并通过物联网实现用户对不同开关面板的适配, 实现对远程开关, 定时开关和光感开关等功能. 免打孔, 免接线的特点以求让用户以最低的适应成本使用物联网技术.

设备演示视频

2 产品亮点

  • 支持腾讯连连小程序扫描二维码添加设备.
  • 腾讯连连小程序中实现自定义H5页面: 设备上报的按键状态会在UI界面上直观地显现出来.
  • 通过TOS Tiny快速接入腾讯云IoT Explorer平台.
  • 设备完成开关操作后, 按键触手会自动回到起始位置, 不妨碍原开关面板的正常使用.
  • 基于事件驱动的设计, 设备支持在移动过程中插入执行新的按键操作.
  • 未来将通过小程序配置设备以适应不同按键个数的开关面板和触键幅度.
  • 未来将接入homeassistant和各种智能音箱以实现联动.

3 产品硬件架构

3.1 组成架构

非侵入式86型智能开关硬件组成架构
非侵入式86型智能开关硬件组成架构

3.2 沁恒CH32V307_EVB简介

CH32V_EVB是腾讯物联网操作系统TencentOS tiny 团队联合沁恒微电子设计的一款物联网评估板, 其采用沁恒RISC-V MCU CH32V307VCT6芯片. 而该芯片是采用基于沁恒自研RISC-V架构微处理器青稞V4架构. 在该开发板上可充分学习评估TencentOS tiny 基础内核、RISC-V IP核架构和IoT组件功能.

ESP8266

作为TOS Tiny系列开发板的一员, CH32V_EVB自然少不了板载一个ESP8266 WIFI模块. 通过开发板上的简单跳线的即可进行烧录和测试. 将腾讯云物联网平台提供的ESP8266固件烧录进ESP8266模块, 在加上TOS Tiny系统加持下, 可以实现在几乎在无代码添加的情况下让MCU快速上云.

3.3 THB6128步进电机驱动模块

THB6128是一款双全桥MOSFET, 低导通电阻的电机驱动IC. 该模块为电机提供独立电源供应, 并接受主控芯片输出的转速脉冲信号, 方向信号和使能信号以驱动电机运转, 且模块对主控的信号均采取光耦隔离的保护措施.

该模块采用信号:共阳极接线法, 即CP+/DIR+/EN+接到开发板+3.3V端. 当CP-/DIR-/EN-针脚为低电平时, 方为输出有效信号.

模块电流设定拨码开关(1/2/3/4): ON/ON/ON/ON(0.7A)

模块细分设定拨码开关(1/2/3): ON/OFF/OFF(64细分)

3.4 霍尔传感器3144以及LM393比较器

霍尔传感模块是基于霍尔元件3144设计而成, 元件是一种磁传感器, 用于计算丝杆转动的圈数. 由于丝杆运动与该传感器没有机械干涉, 它相比于限位开关寿命更长且更稳定. 使用宽电压LM393比较器, 通过对霍尔元件信号与电位器比较, 直接输出稳定的高低电平信号到主控芯片. 需要注意该传感器只对某一极磁场敏感.

4 产品方案设计

4.1 产品组成

产品组成框图
产品组成框图

主要抽象出两个概念:

  • 触手(tentacle)
  • 滑台(slider)
触手和滑台.jpg
触手和滑台.jpg

4.2 端侧架构

端侧架构堆叠图
端侧架构堆叠图

主要流程

程序主要流程图.png
程序主要流程图.png

核心代码

主要基于事件驱动回调的方式来实现:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
// g_sw_status: uint16_t. 下发的最新的设备状态.
// g_sw_status_pst: uint16_t. 已操作的缓存的设备状态
// cur_key_pos: 0对应按键位置为起始位置; 1对应开关面板左①号键位...
// 当触手处在 cur_key_pos 号按键位置上时, 进入该回调
void on_over_key_pos(int cur_key_pos)
{
    printf("当前处于%d号按键上:", cur_key_pos);
    int tmp = 1 << (cur_key_pos - 1);
    if (((g_sw_status ^ g_sw_status_pst) & tmp) != 0)
    {
        if ((g_sw_status & tmp) != 0 && (g_sw_status_pst & tmp) == 0)
        {
            // 按键从关闭-->打开
            printf("打开按键\n");
            tentable_push(PUSH_METHOD_ON);
            g_sw_status_pst = g_sw_status_pst | (g_sw_status & tmp);
        }
        else //if (g_sw_status & tmp == 0 && g_sw_status_pst & tmp != 0)
        {
            // 按键从打开-->关闭
            printf("关闭按键\n");
            tentable_push(PUSH_METHOD_OFF);
            g_sw_status_pst = g_sw_status_pst & ~(g_sw_status_pst & tmp);
        }
        tos_task_delay(1000);
    }
}

监控任务:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
void monitor_task_entry(void* arg)
{
    ...     // 一些值的初始化
    while (1)
    {
        switch (get_key())          // 获取测试按键
        {...} 
        ...
        LCD_ShowString(...);        // 通过LCD输出测试信息
        // 当按键开关量发生变化
        while(g_sw_status != g_sw_status_pst)
        {
            // 阻塞方法. 滑台移动到下一个键位, 并返回到达键位值.
            // 若滑台处在末尾键位, 则改变滑台的运动方向
            ret = slider_moveNextStep();
            if (ret < 0)
            {
                printf("moveNextStep=>%d\n", ret);
                break;
            }
            // 触发到达键位时间
            on_over_key_pos(ret);
        }
        // 空出CPU给其它任务执行
        tos_task_delay(100);
    }

通信代码:

由于挤出的时间比较仓促, 通信部分代码是直接在智能电灯的demo上改出来的:

连带物模型也懒得改(

就借用了brightness属性进行开关状态量的更新和同步

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
void default_message_handler(mqtt_message_t* msg) {
    ... // 一些初始化操作
    len = strlen(msg->payload);
    if (len <= sizeof (msg->payload) && msg->payload[len-1] == '"')
        msg->payload[len-1] = '\0';
    
    cjson_root = cJSON_Parse((char*)(msg->payload +1));
    if (cjson_root == NULL) {
        ...
        goto exit;
    }
    jmethod = cJSON_GetObjectItem(cjson_root, "method");
    method = cJSON_GetStringValue(jmethod);
    jparams = cJSON_GetObjectItem(cjson_root, "params");
    jbrightness = cJSON_GetObjectItem(jparams, "brightness");
    brightness = jbrightness->valueint;
    if (jmethod == NULL || method == NULL ||
        jparams == NULL || jbrightness == NULL) 
    {
        printf("report reply status parser fail:%X\t%X\t%X\t%X\t%X\t\r\n",
            cjson_root, jmethod, method, jparams, jbrightness);
        event_flag = report_fail;
        goto exit;
    }
    if (strstr(method, "control") == NULL)
    {
        printf("method:%s\r\n", method);
        event_flag = report_fail;
        goto exit;
    }
    g_sw_status = brightness & 0x07;
    printf("g_sw_status:%d\n", g_sw_status);
exit:
    // FIXME: cJSON_Delete只需要对根句柄操作, 否则会崩
    cJSON_Delete(cjson_root);
    .. // 一些归0操作
    return;
}

上报开关状态量部分代码:

代码语言:c
代码运行次数:0
运行
AI代码解释
复制
#define EVENT_DATA_TEMPLATE  "{\\\"method\\\":\\\"report\\\"\\,\\\"clientToken\\\":\\\"00000001\\\"\\,\\\"params\\\":{\\\"brightness\\\":%d}}"
void mqtt_task_entry(void) {
    ...
    while (1) {
        tos_sleep_ms(5000);
        /* use AT+PUB AT command */
        memset(payload, 0, sizeof(payload));
        // 就改了这句↓
        snprintf(payload, sizeof(payload), EVENT_DATA_TEMPLATE, g_sw_status_pst & 0x0F);
        printf("pub payload:%s\n", payload);
        if (tos_tf_module_mqtt_pub(event_topic_name, QOS0, payload) != 0)
        {
            printf("module mqtt pub fail\n");
            break;
        }
        else
        {
            printf("module mqtt pub success\n");
        }
    }
}

4.3 用户交互

采用腾讯连连小程序实现自定义H5页面.

非侵入式86型智能开关腾讯连连H5界面
非侵入式86型智能开关腾讯连连H5界面

只要大致理解腾讯连连H5面板原理: HTML和NodeJS是相对独立的关系, 就不难制作出想要的H5页面.

image.png
image.png

核心代码

前端代码是基于腾讯物联网开发平台提供示例项目魔改而成:https://github.com/tencentyun/iotexplorer-h5-panel-demo

首先是魔改了大按钮为3个大按钮:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  // 渲染顶部大按钮
  const renderHeadPanel = () => {
      ...
      // 将id=="brightness"和类型为int的属性值渲染成3个大按钮
      switch (type) {
      case "int":
      case "float":
        console.log('int/float');
        if (id == "brightness")
        {
          return (
            <HeadBoolPanel
              templateConfig={headTemplateConfig}
              onChange={(value) => doControlDeviceProperty(id, value)}
              value={value as number}
              disabled={disabled}
            />
          );
        }
    }
  }

大按钮由大块的按钮和icon组成, 其中icon的样式反映设备已操作的开关量状态.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 单个按钮的核心代码
<div id="power-switch-body_1"
        className="power-switch-body off"
          onClick={() => {
            if (disabled) 
              return;
            
            if ((value & 0x01) != 0)
            {
              value &= ~0x01;
            }
            else
            {
              value |= 0x01;
            }
            onChange(value);
          }}
        >
          <div id="power-switch-icon_1" className="power-switch-icon off" />
        </div>

按钮按下的处理函数与icon更新:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 设备属性控制
const doControlDeviceProperty = async (propertyId: string, value: unknown) => {
// renderHeadPanel();
// 控制报文
const payload = {
    [propertyId]: value,
};
if (propertyId == 'brightness')
{
    let val_num = value as number;
    let tmp = 0x01; 
    for (let index = 0; index < 3; index++) 
    {
    let id_str = "#power-switch-body_" + (index + 1);
    const body = document.querySelector(id_str);
    if ((val_num & tmp) != 0)
    {
        body?.setAttribute("class", "power-switch-body");          
    }
    else
    {
        body?.setAttribute("class", "power-switch-body off");
    }
    tmp <<= 1;
    }
}

try {
    const res = await sdk.controlDeviceData(payload);
    console.log("[controlDeviceData]", payload, "成功", res);
} catch (err) {
    console.log("[controlDeviceData]", payload, "失败", err);
}
};

通过sdk监听wsEventReport事件, 获取设备上报的已操作的开关量状态信息:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    sdk.on('wsEventReport', (data) => {
      console.log('wsEventReport',  data);
      let isHasBrightness = false;
      let brightness = 0;
      const {Payload, deviceId} = data;
      if (deviceId == sdk.deviceId)
      {
        console.log(`发现设备:${deviceId}`);
        const {params} = Payload;
        if ('params' in Payload)
        {
          if ('brightness' in params)
          {
            brightness = params.brightness;
            isHasBrightness = true;
          }
        }
        if (isHasBrightness)
        {
          let val_num = brightness as number;
          // val_num = Math.round(Math.random() * 100) % 0x08;
          console.log(`val_num:${val_num}`);
          let tmp = 0x01; 
          for (let index = 0; index < 3; index++) 
          {
            let id_str = "#power-switch-icon_" + (index + 1);
            const body = document.querySelector(id_str);
            if ((val_num & tmp) != 0)
            {
              body?.setAttribute("class", "power-switch-icon");          
            }
            else
            {
              body?.setAttribute("class", "power-switch-icon off");
            }
            tmp <<= 1;
          }
        }
      }
    });

编写完所有面板代码和样式后, 可以通过"命令控制台"cd到项目目录, 运行

代码语言:shell
AI代码解释
复制
npm run release

即可在iotexplorer-h5-panel-demo\dist\release下找到:

代码语言:txt
AI代码解释
复制
index.*.js
index.*.css

即可上传到IoT平台:

QQ浏览器截图20220808165118.png
QQ浏览器截图20220808165118.png
QQ浏览器截图20220808165251.png
QQ浏览器截图20220808165251.png

4.4 使用微信开发工具开发腾讯连连自定义H5页面

参考:https://cloud.tencent.com/document/product/1081/67441

安装好NodeJS和whistleJS代理程序并加入环境变量PATH后, 在"命令提示符"中运行:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
w2 start

配置好证书后, cd到项目目录:

代码语言:shell
AI代码解释
复制
npm run dev
....
# 当看到:
「wdm」: Compiled successfully.
# 即成功运行项目, 不要关闭控制台

每当修改项目代码保存时, 后台会自动编译新的程序. 通过"微信开发者工具"输入正确地址并登陆, 即可预览H5页面:

代码语言:txt
AI代码解释
复制
# 请替换括号内容
https://iot.cloud.tencent.com/h5panel/developing?deviceName=(deviceName)&productId=(productId)

4.5 使用真机腾讯连连进行调试

根据4.3的介绍, 将生成的H5页面上传后, 即可:

QQ浏览器截图20220808170812.png
QQ浏览器截图20220808170812.png

使用腾讯连连小程序扫描, 即可在真机调试H5页面和设备.

149eb56bd3d547896f9461dee25d118.jpg
149eb56bd3d547896f9461dee25d118.jpg

5 使用TOS Tiny和腾讯云物联网开发平台全栈开发感受

无论从端侧开发还是前端交互开发, 都有充分的技术支持. 技术栈的设计均是相应领域的所擅长的, 取各家之所长, 所以非常利于嵌入式工程师进行全栈开发. 从主控到ESP8266 的硬件联动, 再到腾讯物联网开发平台和腾讯连连的软件联动, 环环相扣, 代码利用率相当高.

端侧固件代码

https://gitee.com/YJHmath/NI-86-box-ISW

腾讯连连自定义H5页面代码

https://gitee.com/YJHmath/non-invasive86-box-intelligent-switch-h5-pannel

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
666
666
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
【小家Spring】Sping AOP中使用到的那些工具类盘点:AopUtils、AopConfigUtils、AspectJAopUtils 、AopProxyUtils、AopContext
Spring AOP框架的代码结构组织得不可为不好,良好的面向对象的编程思想,其中很有一部分得益于它对代码的结构的把控。良好的封装、分层、隔离。而在其中起到重要作用的,便是本文要盘点的一些工具类。
YourBatman
2019/09/03
2.5K0
Spring AOP,从入门到进阶
我们常常在核心业务逻辑中看到诸如事务管理、日志记录或性能统计等行为,这些行为的代码量一般也就几行,但是却分散在多个类中的多个方法内;这些四处分散的重复代码不仅不利于后期的维护工作,同时也显得核心业务逻辑混乱无章。为了解决这一问题,面向切面编程(Aspect-Oriented Programming)应运而生。不同于面向对象编程(Object-oriented Programming),AOP不再以类(Class)为模块化单元,而是以切面(Aspect)作为模块化单元,也就是通过切面来封装那些四处分散的事务管理、日志记录和性能统计等行为。可能有的人会疑惑,可以将这些行为单独封装起来,并不见得一定要使用AOP啊!别杠,单独封装依然无法保持核心业务逻辑的清清爽爽啊,还是会夹杂在一起,不是吗?顺便提一句,横切关注点(Crosscutting Concern),指的就是事务管理、日志记录和性能统计等行为。
程序猿杜小头
2022/12/01
4000
Spring AOP,从入门到进阶
Spring AOP 注解方式源码解析
在上篇文章 Spring AOP 功能使用详解 中,知道了 Sprig AOP 的一个详细用法,现在的看看Spring 中是如何实现的。
Java技术编程
2020/05/20
5310
【小家Spring】Spring AOP各个组件概述与总结【Pointcut、Advice、Advisor、Advised、TargetSource、AdvisorChainFactory...】
Spring AOP作为整个Spring体系最最重要的分支之一,若干技术都是基于它的(比如事务、异步、缓存等)
YourBatman
2019/09/03
3.8K0
【小家Spring】Spring AOP各个组件概述与总结【Pointcut、Advice、Advisor、Advised、TargetSource、AdvisorChainFactory...】
Spring的AOP底层解析
            基于两种动态代理技术,在Spring中进行了封装,封装出来的类叫做ProxyFactory,表示是创建代理对象的一个工厂,使用起来会更加方便。
忧愁的chafry
2022/10/30
5220
Spring的AOP底层解析
SpringAOP学习–SpringAOP简介及原理
前文对AOP做了介绍,实际项目中,一般不会直接上手手动实现aop,而是使用一些高级封装的aop实现,如SpringAOP。 Spring是一个广泛应用的框架,SpringAOP则是Spring提供的一个标准易用的aop框架,依托Spring的IOC容器,提供了极强的AOP扩展增强能力,对项目开发提供了极大地便利。 前文提到AOP的实现有AspectJ、JDK动态代理、CGLIB动态代理,SpringAOP不是一种新的AOP实现,其底层采用的是JDK/CGLIB动态代理。
全栈程序员站长
2022/09/22
3220
SpringAOP学习–SpringAOP简介及原理
Spring AOP 源码分析 - 筛选合适的通知器
从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析。本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出合适的通知器(Advisor)。在上一篇AOP 源码分析导读一文中,我简单介绍了 AOP 中的一些术语及其对应的源码,部分术语和源码将会在本篇文章中出现。如果大家不熟悉这些术语和源码,不妨去看看。 关于 Spring AOP,我个人在日常开发中用过一些,也参照过 tiny-spring 过写过一个玩具版的 AOP 框架,并写成了文章。正因为前面做了一些准备工作,最近再看 Spring AOP 源码时,觉得也没那么难了。所以如果大家打算看 AOP 源码的话,这里建议大家多做一些准备工作。比如熟悉 AOP 的中的术语,亦或是实现一个简单的 IOC 和 AOP,并将两者整合在一起。经过如此准备,相信大家会对 AOP 会有更多的认识。
田小波
2018/08/01
2K0
Spring AOP 源码分析 - 筛选合适的通知器
spring-aop 之 aop:config
文章目录 开头 aop:config 解析 proxy-target-class & expose-proxy aop:pointcut aop:advisor aop:aspect aop:d
MickyInvQ
2021/10/13
1.3K0
【Spring源码】- 10 Spring AOP核心API
Spring的两大核心:IoC和AOP,IoC作为Spring的根基,通过大量的扩展点让系统轻而易举的就可以实现良好的扩展性,而AOP和IoC结合在一起,类似于发生强大化学反应一样,将Spring的功能性又提高了一个层次。Spring中也有大量使用AOP场景,比如@Configuration、数据库事务、mybatis mapper接口注入等等。
Reactor2020
2023/03/22
2820
【Spring源码】- 10  Spring AOP核心API
Spring读源码系列之AOP--05---aop常用工具类学习
Spring AOP框架的代码结构组织得不可为不好,良好的面向对象的编程思想,其中很有一部分得益于它对代码的结构的把控。良好的封装、分层、隔离。而在其中起到重要作用的,便是本文要盘点的一些工具类。
大忽悠爱学习
2022/05/10
1.1K0
Spring读源码系列之AOP--05---aop常用工具类学习
Spring事务是怎么通过AOP实现的
阅读此文章需要掌握一定的AOP源码基础知识,可以更好的去理解事务,我在另外一篇文章有提过。
@派大星
2023/07/15
3250
Spring事务是怎么通过AOP实现的
@Aspect注解背后的奥秘--下
上一篇文章我们减少了aop原始时代中通过ProxyFactory和AspectJProxyFactory手动创建代理对象的过程,本文我们来探究一下新生代中aop自动化是如何实现的。
大忽悠爱学习
2023/02/26
1.2K0
@Aspect注解背后的奥秘--下
SpringAop源码分析(基于注解)二:筛选通知器
我们已经知道BeanPostProcessors是在Bean实例化前后起作用的,如果看过前面的文章Spring Ioc源码分析 之 Bean的加载(八):初始化,应该知道Spring是在AbstractAutowireCapableBeanFactory#doCreateBean() 方法中有一个初始化Bean的方法:
周同学
2019/10/24
1K0
【小家Spring】从基于@Transactional全注解方式的声明式事务入手,彻底掌握Spring事务管理的原理
上篇文章: 【小家Spring】Spring-jdbc的使用以及Spring事务管理的8种方式介绍(声明式事务+编程式事务) 介绍了Spring事务的众多使用方式,其中讲到全注解@Transactional方式的时候一笔带过了,那么本文就以当下最流行的Spring事务的使用方式:全注解的@Transactional使用方式为切入点,扒开Spring事务管理的神秘面纱~
YourBatman
2019/09/03
1.5K0
一文搞懂Spring-AOP原理
文章目录 1. 简介 2. 添加依赖 3. 通知 4. 连接点 5. 切点 6. 切面 7. 实现 8. 注解的实现 9. 切入点表达式 10. 切面执行顺序(Order) 10.1. 注意点 11. Aspect实例化模型 12. 获取参数(args) 13. PointCut 14. PointCuts 15. ClassFilter 16. ClassFilters 17. MethodMatcher 18. MethodMatchers 19. Advice 20. Advisor 20.1.
爱撒谎的男孩
2019/12/31
1.1K0
Spring Transaction,从入门到上瘾
Spring Transaction 针对JDBC API中关于事务管理这一部分进行了高级抽象,它支持两种方式的事务管理,分别是:声明式事务管理 (Declarative Transaction Management) 与 编程式事务管理 (Programmatic Transaction Management) 。声明式事务管理由@Transactional注解来承载,而编程式事务管理则由TransactionManager或TransactionTemplate来实现 (推荐使用后者) 。基于注解的声明式事务管理方式既简洁又优雅,可以有效收敛横切关注逻辑,但极尽简洁的背后却也暗藏陷阱,比如:大事务、事务未正常回滚等。相较于声明式事务管理,编程式事务管理方式对事务粒度的把控更为灵活,这往往很有必要!
程序猿杜小头
2022/12/01
6400
Spring Transaction,从入门到上瘾
(六)Spring源码解析:Spring AOP源码解析
当我们对某些类有横切性的逻辑时,为了不破坏目标类,我们则可以使用AOP的方式将增强逻辑注入到目标类上。为了更清晰的了解AOP的用法,下面我们通过一个使用案例,实现一下面向切面编程。
爪哇缪斯
2023/09/06
8180
(六)Spring源码解析:Spring AOP源码解析
Spring 事务初始化源码分析
在上篇文章 Spring 事务使用详解 中详细介绍了 Spring 事务的使用过程,今天就来看下 Spring 事务是如何来实现,比如 Spring 事务在初始化的时候做了什么,Spring 事务是如何进行事务的提交和回滚的;为了避免篇幅太长,所以分开两篇文章进行分析,这篇文章先来分析下 Spring 事务是如何初始化的,在初始化的时候做了什么。
Java技术编程
2020/05/20
4850
Spring AOP 原理源码深度剖析
概述 AOP(Aspect-Oriented Programming) 面向切面编程。Spring Aop 在 Spring框架中的地位举足轻重,主要用于实现事务、缓存、安全等功能。本篇主要是对源码进行深度分析。
方志朋
2019/06/21
1.1K0
Spring事务AOP实现原理
此篇文章需要有SpringAOP基础,知道AOP底层原理可以更好的理解Spring的事务处理。
用户4283147
2022/10/08
5230
Spring事务AOP实现原理
推荐阅读
相关推荐
【小家Spring】Sping AOP中使用到的那些工具类盘点:AopUtils、AopConfigUtils、AspectJAopUtils 、AopProxyUtils、AopContext
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验