Spring Boot Starter 机制:如何编写自定义 Starter

Spring Boot Starter 机制:如何编写自定义 Starter

原创作者:[您的名字]

阅读时长:约 15-20 分钟

难度:中级-高级

关键词:Spring Boot、Starter、自动配置、自定义启动器、最佳实践


📖 前言

Spring Boot 的核心优势之一就是"约定优于配置",而 Starter 机制正是这一理念的完美体现。通过引入各种 Starter,我们只需在 pom.xml 中添加一个依赖,就能自动获得完整的配置和功能集成。

但你有没有想过:这些 Starter 是如何工作的?我们能否编写自己的 Starter? 本文将深入 Spring Boot 3.x 源码,剖析自动配置原理,并手把手教你编写一个生产级别的自定义 Starter。


🎯 目录

  1. [Spring Boot Starter 原理深度剖析](#Spring Boot Starter 原理深度剖析)
  2. 自动配置核心机制
  3. [编写自定义 Starter 的完整流程](#编写自定义 Starter 的完整流程)
  4. [生产级 Starter 最佳实践](#生产级 Starter 最佳实践)
  5. [实战案例:Redis 分布式锁 Starter](#实战案例:Redis 分布式锁 Starter)
  6. 常见问题与解决方案
  7. 总结与展望

1. Spring Boot Starter 原理深度剖析

1.1 什么是 Starter?

Spring Boot Starter 是一组便捷的依赖描述符,你可以将其包含在应用中。通过获得一组你需要的依赖项(如 Web、测试、数据访问等),你就不需要一个个地复制粘贴依赖配置。

官方 Starter 命名规范: - 官方:spring-boot-starter-* - 第三方:*-spring-boot-starter

复制代码
graph LR
    A[应用引入 Starter] --> B[自动配置触发]
    B --> C[条件注解评估]
    C --> D[Bean 实例化]
    D --> E[功能可用]
    
    style A fill:#e1f5fe
    style B fill:#fff9c4
    style C fill:#f1f8e9
    style D fill:#fce4ec
    style E fill:#e8f5e9

1.2 Spring Boot 3.x 自动配置源码剖析

让我们深入 Spring Boot 3.3.x 源码,看看自动配置是如何工作的。

核心注解:@SpringBootApplication
java 复制代码
#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}// Spring Boot 3.3.5`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@Target(ElementType.TYPE)`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@Retention(RetentionPolicy.RUNTIME)`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@Documented`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@Inherited`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@SpringBootConfiguration  // 标记为配置类`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@EnableAutoConfiguration  // 启用自动配置(核心)`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}public @interface SpringBootApplication {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}    // ... 省略其他代码`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/SpringBootApplication.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // 标记为配置类
@EnableAutoConfiguration  // 启用自动配置(核心)
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    // ... 省略其他代码
}}
自动配置导入:@EnableAutoConfiguration
java 复制代码
#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}// Spring Boot 3.3.5`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}    @Override`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}    public String[] selectImports(AnnotationMetadata annotationMetadata) {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        if (!isEnabled(annotationMetadata)) {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}            return NO_IMPORTS;`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        }`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 1. 加载自动配置候选类`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        AutoConfigurationEntry autoConfigurationEntry = `
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}            getAutoConfigurationEntry(annotationMetadata);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 2. 返回需要导入的配置类全限定名`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}    }`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        if (!isEnabled(annotationMetadata)) {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}            return EMPTY_ENTRY;`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        }`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 3. 获取注解属性`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        AnnotationAttributes attributes = getAttributes(annotationMetadata);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 4. 从 META-INF/spring.factories 或 `
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        //    加载候选配置类`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        List<String> configurations = getCandidateConfigurations(`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}            annotationMetadata, attributes);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 5. 去重`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        configurations = removeDuplicates(configurations);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 6. 排除指定的配置类`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        Set<String> exclusions = getExclusions(annotationMetadata, attributes);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        checkExcludedClasses(configurations, exclusions);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        configurations.removeAll(exclusions);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 7. 过滤掉不满足条件的配置(重要!)`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        configurations = getConfigurationClassFilter().filter(configurations);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        // 8. 触发自动配置导入事件`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        fireAutoConfigurationImportEvents(configurations, exclusions);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}        return new AutoConfigurationEntry(configurations, exclusions);`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}    }`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/AutoConfigurationImportSelector.java
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        }
        // 1. 加载自动配置候选类
        AutoConfigurationEntry autoConfigurationEntry = 
            getAutoConfigurationEntry(annotationMetadata);
        // 2. 返回需要导入的配置类全限定名
        return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    }

    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;
        }
        // 3. 获取注解属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        // 4. 从 META-INF/spring.factories 或 
        //    META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
        //    加载候选配置类
        List<String> configurations = getCandidateConfigurations(
            annotationMetadata, attributes);
        // 5. 去重
        configurations = removeDuplicates(configurations);
        // 6. 排除指定的配置类
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        // 7. 过滤掉不满足条件的配置(重要!)
        configurations = getConfigurationClassFilter().filter(configurations);
        // 8. 触发自动配置导入事件
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return new AutoConfigurationEntry(configurations, exclusions);
    }
}}

关键变化:Spring Boot 2.7 vs 3.x

特性 Spring Boot 2.7 Spring Boot 3.x
配置文件位置 META-INF/spring.factories META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件格式 Properties 格式(键值对) 纯文本(每行一个全限定类名)
兼容性 向后兼容 spring.factories 优先使用新格式,降级兼容旧格式
加载性能 单文件加载所有配置 分散加载,按需加载
自动配置加载流程
复制代码
sequenceDiagram
    participant App as 应用启动
    participant A as @EnableAutoConfiguration
    participant L as AutoConfigurationImportSelector
    participant F as 配置文件加载器
    participant C as 条件注解处理器
    participant B as Bean 容器

    App->>A: 读取注解
    A->>L: 调用 selectImports()
    L->>F: 加载 AutoConfiguration.imports
    F-->>L: 返回候选配置类列表
    L->>L: 去重、排除、过滤
    L->>C: 评估 @ConditionalOnClass 等条件
    C-->>L: 返回满足条件的配置
    L-->>A: 返回最终配置类列表
    A->>B: 注册为 @Configuration
    B->>B: 实例化 Bean

2. 自动配置核心机制

2.1 条件注解体系

Spring Boot 提供了一组强大的条件注解,用于控制 Bean 的创建时机。

核心条件注解对比
注解 作用 示例场景
@ConditionalOnClass classpath 中存在指定类 当 Redis 存在时配置 RedisTemplate
@ConditionalOnMissingClass classpath 中不存在指定类 当没有其他数据源时配置默认数据源
@ConditionalOnBean 容器中存在指定 Bean 当已有 DataSource 时配置 JPA
@ConditionalOnMissingBean 容器中不存在指定 Bean 提供默认实现,允许用户覆盖
@ConditionalOnProperty 配置文件中属性匹配 通过开关控制功能启用
@ConditionalOnResource 指定资源存在 当配置文件存在时加载配置
@ConditionalOnWebApplication Web 应用环境 仅在 Web 应用中配置 Servlet
@ConditionalOnNotWebApplication 非 Web 应用环境 仅在非 Web 应用中配置调度任务
条件注解源码示例
java 复制代码
#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}// Spring Boot 3.3.5`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}@Target({ ElementType.TYPE, ElementType.METHOD })`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}@Retention(RetentionPolicy.RUNTIME)`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}@Documented`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}@Conditional(OnClassCondition.class)  // 条件判断逻辑`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}public @interface ConditionalOnClass {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}    Class<?>[] value() default {};  // 使用 Class 对象`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}    String[] name() default {};     // 使用全限定类名`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}}`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}// 条件判断逻辑`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}class OnClassCondition extends FilteringSpringBootCondition {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}    @Override`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}            AutoConfigurationMetadata autoConfigurationMetadata) {`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}        // 1. 检查 ClassLoader 是否能加载指定类`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}        // 2. 返回匹配结果`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}    }`
`#// Spring Boot 3.3.5
// 文件路径:org/springframework/boot/autoconfigure/condition/ConditionalOnClass.java
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnClassCondition.class)  // 条件判断逻辑
public @interface ConditionalOnClass {
    Class<?>[] value() default {};  // 使用 Class 对象
    String[] name() default {};     // 使用全限定类名
}

// 条件判断逻辑
class OnClassCondition extends FilteringSpringBootCondition {
    @Override
    public ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses,
            AutoConfigurationMetadata autoConfigurationMetadata) {
        // 1. 检查 ClassLoader 是否能加载指定类
        // 2. 返回匹配结果
    }
}}
实际应用示例
java 复制代码
#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}@Configuration`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}@ConditionalOnProperty(`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    prefix = "spring.redis",  // 配置前缀`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    name = "enabled",         // 配置项`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    havingValue = "true",     // 期望值`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    matchIfMissing = true     // 默认启用`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
})`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}public class RedisAutoConfiguration {`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    @Bean`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    public RedisConnectionFactory redisConnectionFactory() {`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}        return new LettuceConnectionFactory();`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    }`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    @Bean`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    @ConditionalOnMissingBean`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    public RedisTemplate<Object, Object> redisTemplate(`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}            RedisConnectionFactory redisConnectionFactory) {`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}        RedisTemplate<Object, Object> template = new RedisTemplate<>();`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}        template.setConnectionFactory(redisConnectionFactory);`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}        return template;`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}    }`
`#@Configuration
@ConditionalOnClass(RedisOperations.class)  // 当 Redis 类存在时
@ConditionalOnMissingBean(name = "redisTemplate")  // 当用户未自定义时
@ConditionalOnProperty(
    prefix = "spring.redis",  // 配置前缀
    name = "enabled",         // 配置项
    havingValue = "true",     // 期望值
    matchIfMissing = true     // 默认启用
)
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 RedisConnectionFactory 时
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }

    @Bean
    @ConditionalOnMissingBean
    public RedisTemplate<Object, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }
}}

2.2 自动配置排序

Spring Boot 使用 @AutoConfigurationOrder@AutoConfigureBefore/After 控制配置类的加载顺序。

java 复制代码
#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}// 示例:数据源自动配置`
`#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级`
`#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前`
`#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}public class DataSourceAutoConfiguration {`
`#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}    // ...`
`#// 示例:数据源自动配置
@AutoConfigurationOrder(Ordered.HIGHEST_PRECEDENCE)  // 最高优先级
@AutoConfigurationBefore(MyBatisAutoConfiguration.class)  // 在 MyBatis 之前
public class DataSourceAutoConfiguration {
    // ...
}}

加载优先级: 1. @AutoConfigurationOrder 数值越小,优先级越高 2. @AutoConfigureBefore 指定在某个配置之前加载 3. @AutoConfigureAfter 指定在某个配置之后加载


3. 编写自定义 Starter 的完整流程

3.1 项目结构设计

一个标准的 Starter 项目应包含以下模块:

复制代码
custom-spring-boot-starter/
├── custom-spring-boot-starter/          # 自动配置模块(核心)
│   ├── pom.xml
│   └── src/main/java/
│       ├── com/example/custom/
│       │   ├── CustomProperties.java           # 配置属性类
│       │   ├── CustomAutoConfiguration.java    # 自动配置类
│       │   └── CustomService.java              # 核心服务类
│       └── resources/
│           └── META-INF/
│               └── spring/
│                   └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
└── custom-spring-boot-starter-example/    # 示例模块(可选)
    └── ...

3.2 创建项目

模块 1:custom-spring-boot-starter

pom.xml 配置:

复制代码
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project><?xml version="1.0" encoding="UTF-8"?>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project><project xmlns="http://maven.apache.org/POM/4.0.0"
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>         https://maven.apache.org/xsd/maven-4.0.0.xsd">
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <modelVersion>4.0.0</modelVersion>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <parent>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <groupId>org.springframework.boot</groupId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <artifactId>spring-boot-starter-parent</artifactId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <version>3.3.5</version>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <relativePath/>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    </parent>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <groupId>com.example</groupId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <artifactId>custom-spring-boot-starter</artifactId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <version>1.0.0</version>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <name>Custom Spring Boot Starter</name>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <description>Custom starter for demo purposes</description>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <properties>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <java.version>17</java.version>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    </properties>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    <dependencies>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <groupId>org.springframework.boot</groupId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <artifactId>spring-boot-autoconfigure</artifactId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        </dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <!-- 配置处理器(生成元数据,IDE 提示) -->
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <groupId>org.springframework.boot</groupId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <artifactId>spring-boot-configuration-processor</artifactId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <optional>true</optional>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        </dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <!-- Lombok(可选,简化代码) -->
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        <dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <groupId>org.projectlombok</groupId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <artifactId>lombok</artifactId>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>            <optional>true</optional>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>        </dependency>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>    </dependencies>
#<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.5</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>custom-spring-boot-starter</artifactId>
    <version>1.0.0</version>
    <name>Custom Spring Boot Starter</name>
    <description>Custom starter for demo purposes</description>
    
    <properties>
        <java.version>17</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot 自动配置依赖(不包含 starter) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
        
        <!-- 配置处理器(生成元数据,IDE 提示) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- Lombok(可选,简化代码) -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project></project>
步骤 1:创建配置属性类
java 复制代码
#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}package com.example.custom;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}import lombok.Data;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}import org.springframework.boot.context.properties.ConfigurationProperties;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}import org.springframework.stereotype.Component;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}/**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
} * 自定义配置属性类`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
} * 配置前缀:custom.demo`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
} */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}@Data`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}@Component`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}public class CustomProperties {`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     * 是否启用自定义功能`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    private boolean enabled = true;  // 默认值`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     * 自定义名称`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    private String name = "Default";`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     * 自定义最大数量`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    private int maxCount = 100;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     * 高级配置`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}     */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    private Advanced advanced = new Advanced();`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    @Data`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    public static class Advanced {`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}        /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}         * 超时时间(毫秒)`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}         */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}        private long timeout = 5000L;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}        `
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}        /**`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}         * 是否启用缓存`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}         */`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}        private boolean cacheEnabled = false;`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}    }`
`#package com.example.custom;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
 * 自定义配置属性类
 * 配置前缀:custom.demo
 */
@Data
@Component
@ConfigurationProperties(prefix = "custom.demo")  // 配置文件中的前缀
public class CustomProperties {
    
    /**
     * 是否启用自定义功能
     */
    private boolean enabled = true;  // 默认值
    
    /**
     * 自定义名称
     */
    private String name = "Default";
    
    /**
     * 自定义最大数量
     */
    private int maxCount = 100;
    
    /**
     * 高级配置
     */
    private Advanced advanced = new Advanced();
    
    @Data
    public static class Advanced {
        /**
         * 超时时间(毫秒)
         */
        private long timeout = 5000L;
        
        /**
         * 是否启用缓存
         */
        private boolean cacheEnabled = false;
    }
}}
步骤 2:创建核心服务类
java 复制代码
#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}package com.example.custom;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}import lombok.extern.slf4j.Slf4j;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}import org.springframework.beans.factory.annotation.Autowired;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}/**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
} * 自定义核心服务类`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
} */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}@Slf4j`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}public class CustomService {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    private final CustomProperties properties;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    // 构造器注入(推荐)`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    @Autowired`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    public CustomService(CustomProperties properties) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        this.properties = properties;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        log.info("CustomService 初始化完成,配置:{}", properties);`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    /**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}     * 执行自定义逻辑`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}     */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    public String process(String input) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        if (!properties.isEnabled()) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}            log.warn("自定义功能未启用");`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}            return "功能未启用";`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}            input, properties.getName(), properties.getMaxCount());`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        return String.format("处理结果:[%s] - %s", `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}            properties.getName(), input);`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    /**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}     * 获取当前配置信息`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}     */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    public CustomProperties getProperties() {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}        return properties;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义核心服务类
 */
@Slf4j
public class CustomService {
    
    private final CustomProperties properties;
    
    // 构造器注入(推荐)
    @Autowired
    public CustomService(CustomProperties properties) {
        this.properties = properties;
        log.info("CustomService 初始化完成,配置:{}", properties);
    }
    
    /**
     * 执行自定义逻辑
     */
    public String process(String input) {
        if (!properties.isEnabled()) {
            log.warn("自定义功能未启用");
            return "功能未启用";
        }
        
        log.info("处理输入:{}, 使用配置:name={}, maxCount={}", 
            input, properties.getName(), properties.getMaxCount());
        
        return String.format("处理结果:[%s] - %s", 
            properties.getName(), input);
    }
    
    /**
     * 获取当前配置信息
     */
    public CustomProperties getProperties() {
        return properties;
    }
}}
步骤 3:创建自动配置类
java 复制代码
#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}package com.example.custom;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import lombok.extern.slf4j.Slf4j;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.boot.autoconfigure.AutoConfiguration;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.boot.context.properties.EnableConfigurationProperties;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}import org.springframework.context.annotation.Bean;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}/**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
} * 自定义自动配置类`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
} * 这是 Starter 的核心,负责创建和注册 Bean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
} */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}@Slf4j`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}@ConditionalOnProperty(`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    prefix = "custom.demo",`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    name = "enabled",`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    havingValue = "true",`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    matchIfMissing = true  // 默认启用`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
})`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}public class CustomAutoConfiguration {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    /**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     * 创建 CustomService Bean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     * @ConditionalOnMissingBean:允许用户自定义覆盖`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    @Bean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    public CustomService customService(CustomProperties properties) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        log.info("正在创建 CustomService Bean...");`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        return new CustomService(properties);`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    /**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     * 可选:创建其他辅助 Bean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    @Bean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    @ConditionalOnMissingBean`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    @ConditionalOnProperty(`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        prefix = "custom.demo.advanced",`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        name = "cache-enabled",`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        havingValue = "true"`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    )`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    public CustomCacheManager customCacheManager(CustomProperties properties) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        log.info("启用自定义缓存管理器,超时时间:{}ms", `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}            properties.getAdvanced().getTimeout());`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        return new CustomCacheManager(properties.getAdvanced().getTimeout());`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    /**`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     * 简单的缓存管理器示例`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}     */`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    public static class CustomCacheManager {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        private final long timeout;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        public CustomCacheManager(long timeout) {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}            this.timeout = timeout;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        `
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        public long getTimeout() {`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}            return timeout;`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}        }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}    }`
`#package com.example.custom;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * 自定义自动配置类
 * 这是 Starter 的核心,负责创建和注册 Bean
 */
@Slf4j
@AutoConfiguration  // Spring Boot 3.x 使用此注解替代 @Configuration
@ConditionalOnClass(CustomService.class)  // 当 CustomService 类存在时
@EnableConfigurationProperties(CustomProperties.class)  // 启用配置属性
@ConditionalOnProperty(
    prefix = "custom.demo",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true  // 默认启用
)
public class CustomAutoConfiguration {
    
    /**
     * 创建 CustomService Bean
     * @ConditionalOnMissingBean:允许用户自定义覆盖
     */
    @Bean
    @ConditionalOnMissingBean  // 当容器中没有 CustomService 时才创建
    public CustomService customService(CustomProperties properties) {
        log.info("正在创建 CustomService Bean...");
        return new CustomService(properties);
    }
    
    /**
     * 可选:创建其他辅助 Bean
     */
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(
        prefix = "custom.demo.advanced",
        name = "cache-enabled",
        havingValue = "true"
    )
    public CustomCacheManager customCacheManager(CustomProperties properties) {
        log.info("启用自定义缓存管理器,超时时间:{}ms", 
            properties.getAdvanced().getTimeout());
        return new CustomCacheManager(properties.getAdvanced().getTimeout());
    }
    
    /**
     * 简单的缓存管理器示例
     */
    public static class CustomCacheManager {
        private final long timeout;
        
        public CustomCacheManager(long timeout) {
            this.timeout = timeout;
        }
        
        public long getTimeout() {
            return timeout;
        }
    }
}}
步骤 4:创建自动配置导入文件

Spring Boot 3.x 方式(推荐):

创建文件:src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

复制代码
com.example.custom.CustomAutoConfiguration

Spring Boot 2.7 兼容方式(降级):

创建文件:src/main/resources/META-INF/spring.factories

复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.custom.CustomAutoConfiguration

3.3 编写单元测试

java 复制代码
#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}package com.example.custom;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}import org.junit.jupiter.api.Test;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}import org.springframework.beans.factory.annotation.Autowired;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}import org.springframework.boot.test.context.SpringBootTest;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}import org.springframework.test.context.TestPropertySource;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}import static org.assertj.core.api.Assertions.assertThat;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}@SpringBootTest(classes = CustomAutoConfiguration.class)`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}class CustomAutoConfigurationTest {`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    `
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    @Autowired(required = false)`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    private CustomService customService;`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    `
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    @Test`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    void testCustomServiceBeanExists() {`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        assertThat(customService).isNotNull();`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    }`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    `
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    @Test`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    @TestPropertySource(properties = {`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        "custom.demo.enabled=true",`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        "custom.demo.name=TestName"`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    })`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    void testCustomServiceProcess() {`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        String result = customService.process("test input");`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        assertThat(result).contains("TestName");`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}        assertThat(result).contains("test input");`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}    }`
`#package com.example.custom;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest(classes = CustomAutoConfiguration.class)
class CustomAutoConfigurationTest {
    
    @Autowired(required = false)
    private CustomService customService;
    
    @Test
    void testCustomServiceBeanExists() {
        assertThat(customService).isNotNull();
    }
    
    @Test
    @TestPropertySource(properties = {
        "custom.demo.enabled=true",
        "custom.demo.name=TestName"
    })
    void testCustomServiceProcess() {
        String result = customService.process("test input");
        assertThat(result).contains("TestName");
        assertThat(result).contains("test input");
    }
}}

3.4 编写配置元数据(可选但推荐)

创建文件:src/main/resources/META-INF/spring-configuration-metadata.json

复制代码
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}{
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}  "groups": [
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "com.example.custom.CustomProperties",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "sourceType": "com.example.custom.CustomProperties",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "自定义功能配置"
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    }
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}  ],
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}  "properties": [
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo.enabled",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "java.lang.Boolean",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "是否启用自定义功能",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "defaultValue": true
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    },
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo.name",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "java.lang.String",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "自定义名称",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "defaultValue": "Default"
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    },
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo.max-count",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "java.lang.Integer",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "自定义最大数量",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "defaultValue": 100
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    },
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo.advanced.timeout",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "java.lang.Long",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "超时时间(毫秒)",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "defaultValue": 5000
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    },
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    {
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "name": "custom.demo.advanced.cache-enabled",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "type": "java.lang.Boolean",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "description": "是否启用缓存",
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}      "defaultValue": false
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}    }
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}  ],
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}  "hints": []
#{
  "groups": [
    {
      "name": "custom.demo",
      "type": "com.example.custom.CustomProperties",
      "sourceType": "com.example.custom.CustomProperties",
      "description": "自定义功能配置"
    }
  ],
  "properties": [
    {
      "name": "custom.demo.enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用自定义功能",
      "defaultValue": true
    },
    {
      "name": "custom.demo.name",
      "type": "java.lang.String",
      "description": "自定义名称",
      "defaultValue": "Default"
    },
    {
      "name": "custom.demo.max-count",
      "type": "java.lang.Integer",
      "description": "自定义最大数量",
      "defaultValue": 100
    },
    {
      "name": "custom.demo.advanced.timeout",
      "type": "java.lang.Long",
      "description": "超时时间(毫秒)",
      "defaultValue": 5000
    },
    {
      "name": "custom.demo.advanced.cache-enabled",
      "type": "java.lang.Boolean",
      "description": "是否启用缓存",
      "defaultValue": false
    }
  ],
  "hints": []
}}

作用: 在 IDE(如 IntelliJ IDEA、VS Code)中提供自动补全和提示。


4. 生产级 Starter 最佳实践

4.1 命名规范

类型 命名规范 示例
官方 Starter spring-boot-starter-* spring-boot-starter-web
第三方 Starter *-spring-boot-starter mybatis-spring-boot-starter
自动配置类 *AutoConfiguration RedisAutoConfiguration
配置属性类 *Properties RedisProperties

4.2 版本管理

方案 1:使用 Spring Boot BOM

复制代码
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement><dependencyManagement>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>    <dependencies>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>        <dependency>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <groupId>org.springframework.boot</groupId>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <artifactId>spring-boot-dependencies</artifactId>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <version>3.3.5</version>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <type>pom</type>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <scope>import</scope>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>        </dependency>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>    </dependencies>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>3.3.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement></dependencyManagement>

方案 2:自定义 BOM

复制代码
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement><dependencyManagement>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>    <dependencies>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>        <dependency>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <groupId>com.example</groupId>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <artifactId>custom-spring-boot-starter-bom</artifactId>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <version>1.0.0</version>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <type>pom</type>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>            <scope>import</scope>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>        </dependency>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>    </dependencies>
#<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>custom-spring-boot-starter-bom</artifactId>
            <version>1.0.0</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement></dependencyManagement>

4.3 依赖管理原则

复制代码
graph TD
    A[Starter 依赖设计] --> B{必须依赖?}
    B -->|是| C[添加为 compile 依赖]
    B -->|否| D[添加为 optional 依赖]
    C --> E[示例: spring-boot-autoconfigure]
    D --> F[示例: Redis 驱动、Lombok]
    
    style A fill:#e1f5fe
    style E fill:#c8e6c9
    style F fill:#ffccbc

规则: - compile 范围: Spring Boot 核心依赖、必须的运行时依赖 - optional 范围: 可选功能依赖(如数据库驱动) - provided 范围: 用户应用提供的依赖(如 Lombok)

4.4 配置优先级设计

java 复制代码
#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}@ConfigurationProperties(prefix = "custom.demo")`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}public class CustomProperties {`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    `
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    // 1. 提供合理的默认值`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    private boolean enabled = true;`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    `
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    // 2. 允许用户覆盖`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    private String name = "Default";`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    `
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    // 3. 支持嵌套配置`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    private Advanced advanced = new Advanced();`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    `
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    // 4. 使用 JSR-303 校验`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    @Min(1)`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    @Max(10000)`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    private int maxCount = 100;`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    `
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    @NotNull`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}    private String requiredField;`
`#@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    
    // 1. 提供合理的默认值
    private boolean enabled = true;
    
    // 2. 允许用户覆盖
    private String name = "Default";
    
    // 3. 支持嵌套配置
    private Advanced advanced = new Advanced();
    
    // 4. 使用 JSR-303 校验
    @Min(1)
    @Max(10000)
    private int maxCount = 100;
    
    @NotNull
    private String requiredField;
}}

4.5 日志规范

java 复制代码
#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}@Slf4j  // 使用 Lombok`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}public class CustomService {`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}    `
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}    public void doSomething() {`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        // 1. 启动时记录关键信息`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        log.info("CustomService 启动,配置:{}", properties);`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        `
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        // 2. 调试时使用 debug 级别`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        log.debug("处理请求:{}", request);`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        `
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        // 3. 警告潜在问题`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        `
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        // 4. 错误时记录异常堆栈`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}        log.error("处理失败", exception);`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}    }`
`#@Slf4j  // 使用 Lombok
public class CustomService {
    
    public void doSomething() {
        // 1. 启动时记录关键信息
        log.info("CustomService 启动,配置:{}", properties);
        
        // 2. 调试时使用 debug 级别
        log.debug("处理请求:{}", request);
        
        // 3. 警告潜在问题
        log.warn("配置项 {} 已废弃,请使用 {}", oldKey, newKey);
        
        // 4. 错误时记录异常堆栈
        log.error("处理失败", exception);
    }
}}

5. 实战案例:Redis 分布式锁 Starter

5.1 需求分析

实现一个 Redis 分布式锁 Starter,支持: - 自动配置 RedisTemplate - 提供分布式锁接口 - 支持锁超时、重试 - 支持注解式声明锁

5.2 项目结构

复制代码
redis-lock-spring-boot-starter/
├── redis-lock-spring-boot-starter/
│   ├── src/main/java/
│   │   └── com/example/redislock/
│   │       ├── RedisLockProperties.java          # 配置属性
│   │       ├── RedisLockAutoConfiguration.java   # 自动配置
│   │       ├── RedisLockService.java             # 锁服务
│   │       ├── RedisLockAspect.java              # AOP 切面
│   │       └── annotation/
│   │           └── RedisLock.java                # 锁注解
│   └── src/main/resources/
│       └── META-INF/spring/
│           └── org.springframework.boot.autoconfigure.AutoConfiguration.imports

5.3 配置属性类

java 复制代码
#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}package com.example.redislock;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}import lombok.Data;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}import org.springframework.boot.context.properties.ConfigurationProperties;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}@Data`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}@ConfigurationProperties(prefix = "redis.lock")`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}public class RedisLockProperties {`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    `
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    /**`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     * 锁前缀`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     */`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    private String keyPrefix = "lock:";`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    `
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    /**`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     * 默认超时时间(毫秒)`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     */`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    private long defaultTimeout = 30000;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    `
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    /**`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     * 获取锁的重试间隔(毫秒)`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     */`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    private long retryInterval = 100;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    `
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    /**`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     * 最大重试次数(-1 表示无限重试)`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     */`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    private int maxRetries = 3;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    `
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    /**`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     * 是否启用注解支持`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}     */`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}    private boolean annotationEnabled = true;`
`#package com.example.redislock;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

@Data
@ConfigurationProperties(prefix = "redis.lock")
public class RedisLockProperties {
    
    /**
     * 锁前缀
     */
    private String keyPrefix = "lock:";
    
    /**
     * 默认超时时间(毫秒)
     */
    private long defaultTimeout = 30000;
    
    /**
     * 获取锁的重试间隔(毫秒)
     */
    private long retryInterval = 100;
    
    /**
     * 最大重试次数(-1 表示无限重试)
     */
    private int maxRetries = 3;
    
    /**
     * 是否启用注解支持
     */
    private boolean annotationEnabled = true;
}}

5.4 核心锁服务

java 复制代码
#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}package com.example.redislock;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}import lombok.extern.slf4j.Slf4j;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}import org.springframework.data.redis.core.RedisTemplate;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}import org.springframework.data.redis.core.script.DefaultRedisScript;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}import java.util.Collections;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}import java.util.concurrent.TimeUnit;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}/**`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
} * Redis 分布式锁服务`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
} * 基于 Redis SET NX EX 命令实现`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
} */`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}@Slf4j`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}public class RedisLockService {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    private final RedisTemplate<String, Object> redisTemplate;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    private final RedisLockProperties properties;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    // Lua 脚本:确保解锁的原子性`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    private static final String UNLOCK_SCRIPT = `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        "if redis.call('get', KEYS[1]) == ARGV[1] then " +`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        "    return redis.call('del', KEYS[1]) " +`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        "else " +`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        "    return 0 " +`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        "end";`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    public RedisLockService(RedisTemplate<String, Object> redisTemplate,`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                           RedisLockProperties properties) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        this.redisTemplate = redisTemplate;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        this.properties = properties;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    /**`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * 尝试获取锁`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * @param lockKey 锁的键`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * @param requestId 请求标识(用于解锁时验证)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * @param timeout 超时时间(毫秒)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * @return 是否获取成功`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     */`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    public boolean tryLock(String lockKey, String requestId, long timeout) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        String fullKey = properties.getKeyPrefix() + lockKey;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        try {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            Boolean result = redisTemplate.opsForValue().setIfAbsent(`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                fullKey,           // 键`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                requestId,         // 值(用于解锁验证)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                timeout,           // 超时时间`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                TimeUnit.MILLISECONDS`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            );`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            return Boolean.TRUE.equals(result);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        } catch (Exception e) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            log.error("获取锁异常:{}", fullKey, e);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            return false;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    /**`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * 阻塞式获取锁(带重试)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     */`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    public boolean lock(String lockKey, String requestId, long timeout) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        String fullKey = properties.getKeyPrefix() + lockKey;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        long startTime = System.currentTimeMillis();`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        int retries = 0;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        while (true) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            // 尝试获取锁`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            if (tryLock(lockKey, requestId, timeout)) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                log.info("成功获取锁:{}", fullKey);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                return true;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            // 检查是否超过最大重试次数`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            if (properties.getMaxRetries() != -1 && `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                retries >= properties.getMaxRetries()) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                return false;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            // 检查是否超时`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            long elapsed = System.currentTimeMillis() - startTime;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            if (elapsed > timeout) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                log.warn("获取锁超时:{}", fullKey);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                return false;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            // 等待后重试`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            try {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                retries++;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            } catch (InterruptedException e) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                Thread.currentThread().interrupt();`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                return false;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    /**`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     * 释放锁(使用 Lua 脚本保证原子性)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}     */`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    public boolean unlock(String lockKey, String requestId) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        String fullKey = properties.getKeyPrefix() + lockKey;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        try {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            Long result = redisTemplate.execute(`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                script,`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                Collections.singletonList(fullKey),`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}                requestId`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            );`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            boolean success = result != null && result == 1L;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            log.info("释放锁:{}, 结果:{}", fullKey, success);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            return success;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        } catch (Exception e) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            log.error("释放锁异常:{}", fullKey, e);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}            return false;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}        }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}    }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * Redis 分布式锁服务
 * 基于 Redis SET NX EX 命令实现
 */
@Slf4j
public class RedisLockService {
    
    private final RedisTemplate<String, Object> redisTemplate;
    private final RedisLockProperties properties;
    
    // Lua 脚本:确保解锁的原子性
    private static final String UNLOCK_SCRIPT = 
        "if redis.call('get', KEYS[1]) == ARGV[1] then " +
        "    return redis.call('del', KEYS[1]) " +
        "else " +
        "    return 0 " +
        "end";
    
    public RedisLockService(RedisTemplate<String, Object> redisTemplate,
                           RedisLockProperties properties) {
        this.redisTemplate = redisTemplate;
        this.properties = properties;
    }
    
    /**
     * 尝试获取锁
     * 
     * @param lockKey 锁的键
     * @param requestId 请求标识(用于解锁时验证)
     * @param timeout 超时时间(毫秒)
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                fullKey,           // 键
                requestId,         // 值(用于解锁验证)
                timeout,           // 超时时间
                TimeUnit.MILLISECONDS
            );
            
            log.debug("尝试获取锁:{}, 结果:{}", fullKey, result);
            return Boolean.TRUE.equals(result);
            
        } catch (Exception e) {
            log.error("获取锁异常:{}", fullKey, e);
            return false;
        }
    }
    
    /**
     * 阻塞式获取锁(带重试)
     */
    public boolean lock(String lockKey, String requestId, long timeout) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        long startTime = System.currentTimeMillis();
        int retries = 0;
        
        while (true) {
            // 尝试获取锁
            if (tryLock(lockKey, requestId, timeout)) {
                log.info("成功获取锁:{}", fullKey);
                return true;
            }
            
            // 检查是否超过最大重试次数
            if (properties.getMaxRetries() != -1 && 
                retries >= properties.getMaxRetries()) {
                log.warn("获取锁失败,达到最大重试次数:{}", fullKey);
                return false;
            }
            
            // 检查是否超时
            long elapsed = System.currentTimeMillis() - startTime;
            if (elapsed > timeout) {
                log.warn("获取锁超时:{}", fullKey);
                return false;
            }
            
            // 等待后重试
            try {
                TimeUnit.MILLISECONDS.sleep(properties.getRetryInterval());
                retries++;
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return false;
            }
        }
    }
    
    /**
     * 释放锁(使用 Lua 脚本保证原子性)
     */
    public boolean unlock(String lockKey, String requestId) {
        String fullKey = properties.getKeyPrefix() + lockKey;
        
        try {
            DefaultRedisScript<Long> script = new DefaultRedisScript<>(UNLOCK_SCRIPT, Long.class);
            Long result = redisTemplate.execute(
                script,
                Collections.singletonList(fullKey),
                requestId
            );
            
            boolean success = result != null && result == 1L;
            log.info("释放锁:{}, 结果:{}", fullKey, success);
            return success;
            
        } catch (Exception e) {
            log.error("释放锁异常:{}", fullKey, e);
            return false;
        }
    }
}}

5.5 注解式锁支持

锁注解:

java 复制代码
#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}package com.example.redislock.annotation;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}import java.lang.annotation.*;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}import java.util.concurrent.TimeUnit;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}@Target(ElementType.METHOD)`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}@Retention(RetentionPolicy.RUNTIME)`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}@Documented`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}public @interface RedisLock {`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    `
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    /**`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     * 锁的键(支持 SpEL 表达式)`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     * 示例:"'user:' + #userId"`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     */`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    String key();`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    `
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    /**`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     * 超时时间(默认使用配置值)`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     */`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    long timeout() default -1;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    `
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    /**`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     * 时间单位(默认毫秒)`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     */`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    `
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    /**`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     * 是否阻塞等待`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}     */`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}    boolean blocking() default true;`
`#userId"
     */
    String key();
    
    /**
     * 超时时间(默认使用配置值)
     */
    long timeout() default -1;
    
    /**
     * 时间单位(默认毫秒)
     */
    TimeUnit timeUnit() default TimeUnit.MILLISECONDS;
    
    /**
     * 是否阻塞等待
     */
    boolean blocking() default true;
}}

AOP 切面:

java 复制代码
#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}package com.example.redislock;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import com.example.redislock.annotation.RedisLock;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import lombok.extern.slf4j.Slf4j;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.aspectj.lang.ProceedingJoinPoint;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.aspectj.lang.annotation.Around;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.aspectj.lang.annotation.Aspect;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.aspectj.lang.reflect.MethodSignature;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.beans.factory.annotation.Autowired;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.core.DefaultParameterNameDiscoverer;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.core.ParameterNameDiscoverer;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.expression.EvaluationContext;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.expression.Expression;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.expression.spel.standard.SpelExpressionParser;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.expression.spel.support.StandardEvaluationContext;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import org.springframework.stereotype.Component;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import java.util.UUID;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}import java.util.concurrent.TimeUnit;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}@Slf4j`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}@Aspect`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}@Component`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}@ConditionalOnProperty(`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    prefix = "redis.lock",`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    name = "annotation-enabled",`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    havingValue = "true",`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    matchIfMissing = true`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
})`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}public class RedisLockAspect {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    @Autowired`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    private RedisLockService lockService;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    @Autowired`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    private RedisLockProperties properties;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    private final SpelExpressionParser parser = new SpelExpressionParser();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    private final ParameterNameDiscoverer nameDiscoverer = new DefaultParameterNameDiscoverer();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    @Around("@annotation(redisLock)")`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    public Object around(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        // 1. 解析锁键(支持 SpEL 表达式)`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        String lockKey = parseKey(redisLock.key(), joinPoint);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        // 2. 生成唯一请求标识`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        String requestId = UUID.randomUUID().toString();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        // 3. 确定超时时间`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        long timeout = redisLock.timeout() != -1 ? `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            redisLock.timeUnit().toMillis(redisLock.timeout()) : `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            properties.getDefaultTimeout();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        // 4. 尝试获取锁`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        boolean locked;`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        if (redisLock.blocking()) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            locked = lockService.lock(lockKey, requestId, timeout);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        } else {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            locked = lockService.tryLock(lockKey, requestId, timeout);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        if (!locked) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            log.warn("获取锁失败:{}", lockKey);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            throw new RuntimeException("获取分布式锁失败:" + lockKey);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        try {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            // 5. 执行业务逻辑`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            log.debug("获取锁成功,执行方法:{}", lockKey);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            return joinPoint.proceed();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        } finally {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            // 6. 释放锁`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            boolean unlocked = lockService.unlock(lockKey, requestId);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            log.debug("释放锁:{}, 结果:{}", lockKey, unlocked);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    /**`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}     * 解析 SpEL 表达式`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}     */`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    private String parseKey(String key, ProceedingJoinPoint joinPoint) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        if (!key.contains("#")) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            return key;  // 不是 SpEL 表达式,直接返回`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        MethodSignature signature = (MethodSignature) joinPoint.getSignature();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        Object[] args = joinPoint.getArgs();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        EvaluationContext context = new StandardEvaluationContext();`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        if (parameterNames != null) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            for (int i = 0; i < parameterNames.length; i++) {`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}                context.setVariable(parameterNames[i], args[i]);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}            }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        `
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        Expression expression = parser.parseExpression(key);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}        return expression.getValue(context, String.class);`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}    }`
`#")) {
            return key;  // 不是 SpEL 表达式,直接返回
        }
        
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String[] parameterNames = nameDiscoverer.getParameterNames(signature.getMethod());
        Object[] args = joinPoint.getArgs();
        
        EvaluationContext context = new StandardEvaluationContext();
        if (parameterNames != null) {
            for (int i = 0; i < parameterNames.length; i++) {
                context.setVariable(parameterNames[i], args[i]);
            }
        }
        
        Expression expression = parser.parseExpression(key);
        return expression.getValue(context, String.class);
    }
}}

5.6 自动配置类

java 复制代码
#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}package com.example.redislock;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import lombok.extern.slf4j.Slf4j;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.autoconfigure.AutoConfiguration;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.boot.context.properties.EnableConfigurationProperties;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.context.annotation.Bean;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}import org.springframework.data.redis.core.RedisTemplate;`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}@Slf4j`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}@EnableConfigurationProperties(RedisLockProperties.class)`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}@ConditionalOnProperty(`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    prefix = "redis.lock",`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    name = "enabled",`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    havingValue = "true",`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    matchIfMissing = true`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
})`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}public class RedisLockAutoConfiguration {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    `
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    @Bean`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    @ConditionalOnMissingBean`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    public RedisLockService redisLockService(`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}            RedisTemplate<String, Object> redisTemplate,`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}            RedisLockProperties properties) {`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}        log.info("初始化 RedisLockService,配置:{}", properties);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}        return new RedisLockService(redisTemplate, properties);`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}    }`
`#package com.example.redislock;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;

@Slf4j
@AutoConfiguration(after = RedisAutoConfiguration.class)  // 在 Redis 配置之后
@ConditionalOnClass(RedisTemplate.class)  // 当 Redis 存在时
@EnableConfigurationProperties(RedisLockProperties.class)
@ConditionalOnProperty(
    prefix = "redis.lock",
    name = "enabled",
    havingValue = "true",
    matchIfMissing = true
)
public class RedisLockAutoConfiguration {
    
    @Bean
    @ConditionalOnMissingBean
    public RedisLockService redisLockService(
            RedisTemplate<String, Object> redisTemplate,
            RedisLockProperties properties) {
        log.info("初始化 RedisLockService,配置:{}", properties);
        return new RedisLockService(redisTemplate, properties);
    }
}}

5.7 配置文件

application.yml 示例:

复制代码
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: trueredis:
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true  lock:
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    enabled: true
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    key-prefix: "myapp:lock:"
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    default-timeout: 30000  # 30秒
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    retry-interval: 100
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    max-retries: 5
# 30秒
    retry-interval: 100
    max-retries: 5
    annotation-enabled: true    annotation-enabled: true

5.8 使用示例

编程式使用:

java 复制代码
#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}@Service`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}public class OrderService {`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    @Autowired`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    private RedisLockService lockService;`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    public void createOrder(String orderId) {`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}        String requestId = UUID.randomUUID().toString();`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}        `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}        try {`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            // 获取锁`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            boolean locked = lockService.lock(`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}                "order:" + orderId,  // 锁键`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}                requestId,            // 请求标识`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}                10000                 // 超时时间`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            );`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            if (!locked) {`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}                throw new RuntimeException("订单创建中,请稍后重试");`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            }`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            // 执行业务逻辑`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            // ...`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            `
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}        } finally {`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            // 释放锁`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}            lockService.unlock("order:" + orderId, requestId);`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}        }`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}    }`
`#@Service
public class OrderService {
    
    @Autowired
    private RedisLockService lockService;
    
    public void createOrder(String orderId) {
        String requestId = UUID.randomUUID().toString();
        
        try {
            // 获取锁
            boolean locked = lockService.lock(
                "order:" + orderId,  // 锁键
                requestId,            // 请求标识
                10000                 // 超时时间
            );
            
            if (!locked) {
                throw new RuntimeException("订单创建中,请稍后重试");
            }
            
            // 执行业务逻辑
            // ...
            
        } finally {
            // 释放锁
            lockService.unlock("order:" + orderId, requestId);
        }
    }
}}

注解式使用:

java 复制代码
#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}@Service`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}public class UserService {`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}    `
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}    @RedisLock(key = "'user:update:' + #userId", timeout = 10, timeUnit = TimeUnit.SECONDS)`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}    public void updateUser(String userId, User user) {`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}        // 方法执行期间会自动加锁`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}        // ...`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}    }`
`#userId", timeout = 10, timeUnit = TimeUnit.SECONDS)
    public void updateUser(String userId, User user) {
        // 方法执行期间会自动加锁
        // ...
    }
}}

6. 常见问题与解决方案

6.1 自动配置未生效

问题: Starter 依赖引入后,Bean 未自动创建。

排查步骤:

复制代码
graph TD
    A[自动配置未生效] --> B{检查依赖}
    B -->|依赖缺失| C[添加 compile 范围依赖]
    B -->|依赖正常| D{检查配置文件}
    D -->|文件不存在| E[创建 AutoConfiguration.imports]
    D -->|文件存在| F{检查类名}
    F -->|类名错误| G[修正全限定类名]
    F -->|类名正确| H{检查条件注解}
    H -->|条件不满足| I[调整配置或条件]
    H -->|条件满足| J[启用 DEBUG 日志]
    
    style A fill:#ffebee
    style C fill:#c8e6c9
    style E fill:#c8e6c9
    style G fill:#c8e6c9
    style I fill:#c8e6c9
    style J fill:#fff9c4

解决方案:

  1. 启用 DEBUG 日志:

    #logging:
    level:
    org.springframework.boot.autoconfigure: DEBUGlogging:
    #logging:
    level:
    org.springframework.boot.autoconfigure: DEBUG level:
    #logging:
    level:
    org.springframework.boot.autoconfigure: DEBUG org.springframework.boot.autoconfigure: DEBUG

  2. 查看条件评估报告:

    启动时添加参数

    java -jar app.jar --debug# 启动时添加参数

    启动时添加参数

    java -jar app.jar --debugjava -jar app.jar --debug

  3. 手动导入配置类:

java 复制代码
#@SpringBootApplication
@Import(CustomAutoConfiguration.class)  // 手动导入
public class Application {
    // ...
}@SpringBootApplication`
`#@SpringBootApplication
@Import(CustomAutoConfiguration.class)  // 手动导入
public class Application {
    // ...
}@Import(CustomAutoConfiguration.class)  // 手动导入`
`#@SpringBootApplication
@Import(CustomAutoConfiguration.class)  // 手动导入
public class Application {
    // ...
}public class Application {`
`#@SpringBootApplication
@Import(CustomAutoConfiguration.class)  // 手动导入
public class Application {
    // ...
}    // ...`
`#@SpringBootApplication
@Import(CustomAutoConfiguration.class)  // 手动导入
public class Application {
    // ...
}}

6.2 配置属性绑定失败

问题: @ConfigurationProperties 注解的属性无法绑定值。

原因分析:

原因 解决方案
缺少 @EnableConfigurationProperties 在配置类上添加注解
类路径不在扫描范围内 添加 @Component 或手动注册
配置文件路径错误 检查 application.yml/properties 路径
类型不匹配 检查配置值类型与字段类型一致性

解决方案:

java 复制代码
#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}// 方案 1:在配置类上启用`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}@Configuration`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}@EnableConfigurationProperties(CustomProperties.class)`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}public class CustomAutoConfiguration {`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}    // ...`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}}`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}// 方案 2:在属性类上添加组件注解`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}@Component`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}@ConfigurationProperties(prefix = "custom.demo")`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}public class CustomProperties {`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}    // ...`
`#// 方案 1:在配置类上启用
@Configuration
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
    // ...
}

// 方案 2:在属性类上添加组件注解
@Component
@ConfigurationProperties(prefix = "custom.demo")
public class CustomProperties {
    // ...
}}

6.3 Bean 覆盖问题

问题: 自定义 Bean 被 Starter 的默认 Bean 覆盖。

最佳实践:

java 复制代码
#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}// Starter 提供默认实现`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}@Bean`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}@ConditionalOnMissingBean  // 关键:允许用户覆盖`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}public CustomService customService(CustomProperties properties) {`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}    return new CustomService(properties);`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}}`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}// 用户自定义实现`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}@Configuration`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}public class UserConfiguration {`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}    `
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}    @Bean`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}    public CustomService customService(CustomProperties properties) {`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}        // 用户自定义实现会覆盖 Starter 的默认实现`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}        return new UserCustomService(properties);`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}    }`
`#// Starter 提供默认实现
@Bean
@ConditionalOnMissingBean  // 关键:允许用户覆盖
public CustomService customService(CustomProperties properties) {
    return new CustomService(properties);
}

// 用户自定义实现
@Configuration
public class UserConfiguration {
    
    @Bean
    public CustomService customService(CustomProperties properties) {
        // 用户自定义实现会覆盖 Starter 的默认实现
        return new UserCustomService(properties);
    }
}}

6.4 循环依赖问题

问题: Bean 之间相互依赖,启动失败。

解决方案:

java 复制代码
#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案// 方案 1:使用 @Lazy 延迟加载`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案@Configuration`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案public class ConfigA {`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    `
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    @Bean`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    public ServiceA serviceA(@Lazy ServiceB serviceB) {`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案        return new ServiceA(serviceB);`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    }`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案}`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案// 方案 2:使用 Setter 注入代替构造器注入`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案@Configuration`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案public class ConfigB {`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    `
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    @Bean`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    public ServiceB serviceB() {`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案        ServiceB serviceB = new ServiceB();`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案        // 通过 Setter 注入`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案        serviceB.setServiceA(null);  // 后续由 Spring 注入`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案        return serviceB;`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案    }`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案}`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案// 方案 3:重构代码,消除循环依赖`
`#// 方案 1:使用 @Lazy 延迟加载
@Configuration
public class ConfigA {
    
    @Bean
    public ServiceA serviceA(@Lazy ServiceB serviceB) {
        return new ServiceA(serviceB);
    }
}

// 方案 2:使用 Setter 注入代替构造器注入
@Configuration
public class ConfigB {
    
    @Bean
    public ServiceB serviceB() {
        ServiceB serviceB = new ServiceB();
        // 通过 Setter 注入
        serviceB.setServiceA(null);  // 后续由 Spring 注入
        return serviceB;
    }
}

// 方案 3:重构代码,消除循环依赖
// 这是最根本的解决方案// 这是最根本的解决方案

6.5 版本兼容性问题

Spring Boot 2.x → 3.x 迁移注意事项:

变化点 Spring Boot 2.x Spring Boot 3.x 迁移建议
配置文件 spring.factories AutoConfiguration.imports 创建新格式文件
JDK 版本 JDK 8+ JDK 17+ 升级到 JDK 17
javax.* javax.servlet jakarta.servlet 替换包名
@Conditional 旧版条件注解 增强版条件注解 无需修改,向后兼容

迁移步骤:

复制代码
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports# 1. 升级 JDK 到 17+
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsjava -version
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports# 2. 更新 pom.xml
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports<parent>
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports    <groupId>org.springframework.boot</groupId>
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports    <artifactId>spring-boot-starter-parent</artifactId>
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports</parent>
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports# 3. 替换 javax 为 jakarta
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsfind . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports# 4. 创建新格式配置文件
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsmkdir -p src/main/resources/META-INF/spring
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsecho "com.example.CustomAutoConfiguration" > \
# 1. 升级 JDK 到 17+
java -version

# 2. 更新 pom.xml
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.5</version>  <!-- 从 2.7.x 升级 -->
</parent>

# 3. 替换 javax 为 jakarta
find . -name "*.java" -exec sed -i 's/javax\.servlet/jakarta.servlet/g' {} \;

# 4. 创建新格式配置文件
mkdir -p src/main/resources/META-INF/spring
echo "com.example.CustomAutoConfiguration" > \
  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports  src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

7. 总结与展望

7.1 核心要点回顾

本文从 Spring Boot 3.x 源码出发,深入剖析了 Starter 机制的核心原理,并提供了完整的生产级 Starter 开发指南。

关键要点:

  1. 自动配置原理:
    • @EnableAutoConfiguration 触发配置加载
    • AutoConfigurationImportSelector 扫描配置文件
    • 条件注解过滤不满足条件的配置
  2. 配置文件变化:
    • Spring Boot 3.x 使用 AutoConfiguration.imports
    • 向后兼容 spring.factories
  3. 最佳实践:
    • 遵循命名规范
    • 合理设计依赖范围
    • 提供合理的默认值
    • 使用条件注解控制 Bean 创建
    • 编写完整的单元测试

7.2 技术演进趋势

复制代码
timeline
    title Spring Boot Starter 演进史
    section Spring Boot 1.x
        2014 : 引入 spring.factories<br>自动配置机制
    section Spring Boot 2.x
        2017 : 增强条件注解<br>引入 @ConditionalOn* 系列注解
    section Spring Boot 2.7
        2022 : 引入新配置文件格式<br>AutoConfiguration.imports
    section Spring Boot 3.x
        2023 : 默认使用新格式<br>要求 JDK 17+
    section 未来趋势
        2025+ : 更智能的配置推断<br>AI 辅助配置生成

7.3 实战建议

编写 Starter 的决策树:

复制代码
graph TD
    A[需要编写 Starter? ] --> B{功能是否通用?}
    B -->|否| C[直接在项目中配置]
    B -->|是| D{是否需要自动配置?}
    D -->|否| E[提供普通依赖即可]
    D -->|是| F{是否需要条件化?}
    F -->|否| G[简单的 @Configuration]
    F -->|是| H[编写完整的 Starter]
    
    H --> I[遵循最佳实践]
    I --> J[编写完整测试]
    I --> K[提供详细文档]
    I --> L[发布到 Maven 仓库]
    
    style C fill:#ffcdd2
    style E fill:#fff9c4
    style G fill:#c8e6c9
    style H fill:#b2dfdb
    style I fill:#b3e5fc

7.4 进阶学习路径

  1. 深入源码:
    • 阅读 AutoConfigurationImportSelector 源码
    • 研究条件注解实现原理
    • 学习 ConfigurationPropertiesBinding 机制
  2. 扩展功能:
    • 自定义条件注解
    • 实现 ApplicationContextInitializer
    • 开发 EnvironmentPostProcessor
  3. 性能优化:
    • 延迟初始化配置
    • 按需加载依赖
    • 减少不必要的 Bean 创建

7.5 推荐资源

官方文档: - Spring Boot Auto-configuration - Spring Boot Configuration Properties

优秀开源项目: - mybatis-spring-boot-starter - 数据持久化 - spring-boot-starter-data-redis - Redis 集成 - spring-cloud-starter-openfeign - 声明式 HTTP 客户端

实战练习: 1. 编写一个日志切面 Starter 2. 实现一个邮件发送 Starter 3. 开发一个限流 Starter


🔗 附录

A. 完整项目结构

复制代码
redis-lock-spring-boot-starter/
├── pom.xml
├── README.md
├── LICENSE
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/redislock/
│   │   │       ├── RedisLockProperties.java
│   │   │       ├── RedisLockAutoConfiguration.java
│   │   │       ├── RedisLockService.java
│   │   │       ├── RedisLockAspect.java
│   │   │       └── annotation/
│   │   │           └── RedisLock.java
│   │   └── resources/
│   │       ├── META-INF/
│   │       │   └── spring/
│   │       │       └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│   │       └── spring-configuration-metadata.json
│   └── test/
│       └── java/
│           └── com/example/redislock/
│               ├── RedisLockServiceTest.java
│               └── RedisLockAspectTest.java
└── example/
    └── src/
        └── main/
            ├── java/
            │   └── com/example/demo/
            │       └── DemoApplication.java
            └── resources/
                └── application.yml

B. Maven 仓库发布

发布到 Central:

复制代码
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build><distributionManagement>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    <snapshotRepository>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <id>ossrh</id>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    </snapshotRepository>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    <repository>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <id>ossrh</id>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    </repository>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build></distributionManagement>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build><build>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    <plugins>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <!-- GPG 签名插件 -->
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <groupId>org.apache.maven.plugins</groupId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <artifactId>maven-gpg-plugin</artifactId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <version>3.1.0</version>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                <execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <id>sign-artifacts</id>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <phase>verify</phase>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                        <goal>sign</goal>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    </goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                </execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            </executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        </plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <!-- 源码插件 -->
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <groupId>org.apache.maven.plugins</groupId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <artifactId>maven-source-plugin</artifactId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <version>3.3.0</version>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                <execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <id>attach-sources</id>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                        <goal>jar-no-fork</goal>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    </goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                </execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            </executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        </plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <!-- Javadoc 插件 -->
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        <plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <groupId>org.apache.maven.plugins</groupId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <artifactId>maven-javadoc-plugin</artifactId>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <version>3.6.3</version>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            <executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                <execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <id>attach-javadocs</id>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    <goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                        <goal>jar</goal>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                    </goals>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>                </execution>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>            </executions>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>        </plugin>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>    </plugins>
#<distributionManagement>
    <snapshotRepository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/content/repositories/snapshots</url>
    </snapshotRepository>
    <repository>
        <id>ossrh</id>
        <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
    </repository>
</distributionManagement>

<build>
    <plugins>
        <!-- GPG 签名插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-gpg-plugin</artifactId>
            <version>3.1.0</version>
            <executions>
                <execution>
                    <id>sign-artifacts</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>sign</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- 源码插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>3.3.0</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        
        <!-- Javadoc 插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <version>3.6.3</version>
            <executions>
                <execution>
                    <id>attach-javadocs</id>
                    <goals>
                        <goal>jar</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build></build>

发布命令:

复制代码
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release# 1. 清理并编译
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Releasemvn clean install
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release# 2. 部署到远程仓库
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Releasemvn deploy
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release# 3. 登录 Nexus 仓库进行 Release
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release# 访问:https://oss.sonatype.org/
# 1. 清理并编译
mvn clean install

# 2. 部署到远程仓库
mvn deploy

# 3. 登录 Nexus 仓库进行 Release
# 访问:https://oss.sonatype.org/
# 操作:Staging Repositories → Close → Release# 操作:Staging Repositories → Close → Release

C. 测试覆盖率配置

复制代码
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin><plugin>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>    <groupId>org.jacoco</groupId>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>    <artifactId>jacoco-maven-plugin</artifactId>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>    <version>0.8.11</version>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>    <executions>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>        <execution>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            <goals>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>                <goal>prepare-agent</goal>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            </goals>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>        </execution>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>        <execution>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            <id>report</id>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            <phase>test</phase>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            <goals>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>                <goal>report</goal>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>            </goals>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>        </execution>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin>    </executions>
#<plugin>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.8.11</version>
    <executions>
        <execution>
            <goals>
                <goal>prepare-agent</goal>
            </goals>
        </execution>
        <execution>
            <id>report</id>
            <phase>test</phase>
            <goals>
                <goal>report</goal>
            </goals>
        </execution>
    </executions>
</plugin></plugin>

📝 结语

Spring Boot Starter 机制是 Spring Boot "约定优于配置"理念的完美体现。通过本文的学习,你应该掌握了:

✅ Spring Boot 3.x 自动配置的核心原理

✅ 条件注解的使用方法和最佳实践

✅ 完整的自定义 Starter 开发流程

✅ 生产级 Redis 分布式锁 Starter 实现

✅ 常见问题的排查和解决方案

记住: 编写一个好的 Starter,不仅需要技术能力,更需要对用户场景的深入理解。始终站在使用者的角度思考,提供合理默认值、清晰的配置选项和完善的文档。

希望这篇文章能帮助你更好地理解和使用 Spring Boot Starter。如果有任何问题或建议,欢迎在评论区留言讨论!


标签: Spring Boot Starter 自定义启动器 自动配置 最佳实践 Spring Boot 3.x 源码分析

作者简介: [您的简介]
发布时间: 2024-03-30
阅读量: [阅读量]
点赞数: [点赞数]

相关推荐
weixin_704266052 小时前
Spring 注解驱动开发与 Spring Boot 核心知识点梳理
java·spring boot·spring
小江的记录本3 小时前
【Spring注解】Spring生态常见注解——面试高频考点总结
java·spring boot·后端·spring·面试·架构·mvc
计算机学姐3 小时前
基于SpringBoot的奶茶店点餐系统【协同过滤推荐算法+数据可视化统计】
java·vue.js·spring boot·mysql·信息可视化·tomcat·推荐算法
常利兵3 小时前
Spring Boot 实现网络限速:让流量“收放自如”
网络·spring boot·后端
Flittly4 小时前
【SpringAIAlibaba新手村系列】(6)PromptTemplate 提示词模板与变量替换
java·spring boot·agent
yaaakaaang4 小时前
3.springboot,用eclipse轻松创建~
java·spring boot·eclipse
计算机学姐4 小时前
基于SpringBoot的新能源充电桩管理系统
java·vue.js·spring boot·后端·mysql·spring·java-ee
qq5680180764 小时前
Springboot中使用Elasticsearch(部署+使用+讲解 最完整)
spring boot·elasticsearch·jenkins
瑶山4 小时前
SpringBoot + MongoDB 5分钟快速集成:从0到1实操指南
java·数据库·spring boot·后端·mongodb