@ConditionalOnProperty注解

本文详细解析了Spring Boot中@ConditionalOnProperty注解的工作原理及其关键属性matchIfMissing的作用。通过不同配置情况下的实例演示,展示了如何根据配置文件中的属性值来决定是否加载配置类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

条件注解分类

常见的@Conditionalxxx开头的注解我们称之为条件注解,常见的条件注解有

  • class条件注解:@ConditionalOnClass
  • bean条件注解:@ConditionalOnBean
  • 属性条件注解:@ConditionalOnProperty

这几个注解通常会结合使用,一般都是在配置类中使用,SpringBoot各种xxxxAutoCconfiguration都用到了这些注解,这也是SpringBoot自动装配的重要工具。这篇博文主要说一下@ConditionalOnProperty属性条件注解。

简单来讲,一般是在配置类上或者是@Bean修饰的方法上,添加此注解表示一个类是否要被Spring上下文加载,若满足条件则加载,若不满足条件则不加载。

我们在application.properties中配置的各种配置,添加配置之后即生效,就是这么控制的。

主要说一下这个属性matchIfMissing,该属性为true时,配置文件中缺少对应的value或name的对应的属性值,也会注入成功。

app.name=tom

配置类为

@ConditionalOnProperty(prefix = "app",name="name",matchIfMissing =  false)
@Configuration
public class ConfigureOne {

    public ConfigureOne() {
        System.out.println("--------构造ConfigureOne---------");
    }
}
不配置havingValue的值

1.假如没有配置这个name的配置
1.1@ConditionalOnProperty(prefix = “app”,name=“name”,matchIfMissing = false)
假如没有配置这个name的配置,若matchIfMissing为false,则不会加载此配置类
假如配置了这个name的配置,若matchIfMissing为false,则会加载此配置类

1.2@ConditionalOnProperty(prefix = “app”,name=“name”,matchIfMissing = true)
假如没有配置这个name的配置,若matchIfMissing为true,则仍会加载此配置类
假如配置了这个name的配置,若matchIfMissing为true,则会加载此配置类
总结,若未配置havingValue的值,matchIfMissing为true则无论是否有配置都会加载配置类,matchIfMissing为false,有配置加载类,无配置不加载类。

配置错误的havingValue的值

2.1@ConditionalOnProperty(prefix = “app”,name=“name”,havingValue = “name1”,matchIfMissing = false)
假如配置了错误的name值,若matchIfMissing为false,配置类不会加载
假如配置了正确的name值,若matchIfMissing为false,配置类会加载

2.2@ConditionalOnProperty(prefix = “app”,name=“name”,havingValue = “name1”,matchIfMissing = true)
假如配置了错误的name值,若matchIfMissing为true,配置类不会加载
假如配置了正确的name值,若matchIfMissing为true,配置类会加载
总结,只要配置了正确的havingValue值,无论matchIfMissing怎么设置,都会加载,只要配置的havingValue值不正确,无论
matchIfMissing怎么设置,都不会加载。

### Zynq LwIP 示例代码 以下是基于 Zynq 平台的一个简单 LwIP 应用程序示例,该程序展示了如何通过 PS 端的网卡实现 UDP 数据收发。此代码结构参考了常见的嵌入式系统开发流程,并结合了 LwIP 的特性。 #### 初始化与配置 在 Zynq 上使用 LwIP 通常需要完成以下几个步骤: 1. **硬件初始化**:确保 Vivado 和 PetaLinux 已正确配置 ENET 接口。 2. **LwIP 初始化**:调用 `lwip_init()` 函数来启动协议栈。 3. **网络接口绑定**:将物理网卡驱动与 LwIP 协议栈关联。 ```c #include "lwip/init.h" #include "lwip/netif.h" #include "arch/sys_arch.h" // 定义全局变量 struct netif gnetif; void system_setup() { sys_init(); // 系统底层初始化 } void network_setup(struct netif *netif) { ip4_addr_t ipaddr; ip4_addr_t netmask; ip4_addr_t gw; IP4_ADDR(&gw, 192, 168, 1, 1); // 默认网关地址 IP4_ADDR(&ipaddr, 192, 168, 1, 100); // 设备本地IP地址 IP4_ADDR(&netmask, 255, 255, 255, 0); // 子网掩码 netif_add(netif, &ipaddr, &netmask, &gw, NULL, enetif_init, tcpip_input); netif_set_default(netif); netif_set_up(netif); printf("Network interface initialized.\n"); } ``` 上述代码完成了网络接口的基本设置[^1]。 --- #### 主循环逻辑 主函数负责启动 LwIP 协议栈并进入无限循环处理网络事件。 ```c int main(void) { system_setup(); lwip_init(); struct netif netif; network_setup(&netif); while (1) { sys_check_timeouts(); // 处理超时事件 } return 0; } ``` 在此基础上,可以通过扩展支持更复杂的网络功能,例如 TCP 连接管理或自定义数据包处理。 --- #### 基于 Raw API 的 TCP 实现 如果需要使用 LwIP 提供的 Raw API 来建立 TCP 连接,则可以按照以下方法编写: ```c err_t my_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { if (err != ERR_OK || newpcb == NULL) { return ERR_ARG; } tcp_arg(newpcb, arg); // 设置用户参数 tcp_recv(newpcb, my_tcp_recv); // 注册接收回调 return ERR_OK; } err_t my_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { if (!p) { tcp_close(tpcb); // 如果没有更多数据则关闭连接 return ERR_OK; } char buffer[p->tot_len]; memcpy(buffer, p->payload, p->len); printf("Received data: %s\n", buffer); tcp_sent(tpcb, my_tcp_sent); // 注册发送完成后回调 tcp_write(tpcb, buffer, strlen(buffer), 1); // 发送响应数据 pbuf_free(p); // 释放缓冲区 return ERR_OK; } void create_server(uint16_t port) { struct tcp_pcb *pcb = tcp_new(); if (pcb == NULL) { printf("Failed to allocate PCB!\n"); return; } err_t bind_err = tcp_bind(pcb, IP_ANY_TYPE, port); if (bind_err != ERR_OK) { printf("Binding failed with error code: %d\n", bind_err); tcp_delete(pcb); return; } pcb = tcp_listen(pcb); tcp_accept(pcb, my_tcp_accept); printf("Server listening on port %u...\n", port); } ``` 以上代码实现了简单的服务器端逻辑,能够接受客户端连接请求并回显收到的数据[^2]。 --- #### 改进任意长度数据传输 对于需要支持动态大小数据流的应用场景,可引入分片机制或将大数据拆分为多个小片段逐一传递。这可通过调整 `tcp_write` 参数以及监听 `tcp_sent` 回调实现[^4]。 ```c static void send_next_segment(struct tcp_pcb *pcb, uint8_t *data, size_t length) { static size_t offset = 0; size_t chunk_size = MIN(length - offset, MAX_TCP_SEG_SIZE); if (offset >= length) { return; // 所有数据已发送完毕 } tcp_write(pcb, data + offset, chunk_size, TCP_WRITE_FLAG_COPY); offset += chunk_size; } err_t my_tcp_sent(void *arg, struct tcp_pcb *tpcb, u16_t space) { uint8_t *buffer = ...; // 待发送的大数据缓存指针 size_t total_length = ...; // 缓冲区总长度 send_next_segment(tpcb, buffer, total_length); return ERR_OK; } ``` 这种策略允许高效地处理大文件或其他连续型数据流。 --- ###
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值