自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(186)
  • 收藏
  • 关注

原创 深入解析 Spring Environment

Spring框架中的Environment接口是管理应用运行时环境的核心组件,主要负责配置属性和环境配置(Profiles)的抽象与整合。其核心功能包括:通过统一接口获取多来源属性(如配置文件、环境变量等),并支持类型转换和默认值处理;通过Profiles机制实现环境隔离(如开发/生产配置)。属性源按优先级覆盖,从命令行参数到内部配置文件。可通过依赖注入、实现EnvironmentAware接口或ApplicationContext获取该对象,广泛应用于多环境配置、动态属性加载等场景,是Spring配置体系

2025-06-09 14:07:13 662

原创 Spring EnvironmentAware回调机制深度解析与实战

Spring的EnvironmentAware接口允许Bean在初始化阶段访问环境配置。本文介绍了其核心概念、价值及一个多环境邮件服务系统的实战案例。通过实现EnvironmentAware接口,邮件服务能够根据开发和生产环境加载不同配置,并支持动态调整参数。案例包含配置验证器,展示多接口实现和环境参数检查功能,帮助开发者理解如何利用该接口实现环境感知的应用程序配置。

2025-06-09 13:59:27 944

原创 AnnotationConfigApplicationContext初始化源码详解

Spring注解驱动容器启动流程解析 摘要:AnnotationConfigApplicationContext作为Spring基于注解的核心容器,其初始化过程严格遵循Java类加载机制和Spring分层设计。容器启动首先完成父类链初始化:AbstractApplicationContext初始化资源解析器,GenericApplicationContext创建DefaultListableBeanFactory实例。随后执行子类特有逻辑:创建AnnotatedBeanDefinitionReader处理注

2025-06-06 11:36:36 1565

原创 Spring BeanDefinition:Bean 的构建蓝图

Spring IoC容器的核心是BeanDefinition,它作为Bean的元数据载体,定义了类名、作用域、依赖关系等关键信息,指导容器实例化和管理Bean。主要实现类包括RootBeanDefinition(完整定义)、GenericBeanDefinition(通用实现)以及支持注解的ScannedGenericBeanDefinition等。通过BeanDefinition,Spring实现依赖注入、生命周期管理及配置继承等功能,是理解Spring运行机制的基础。

2025-06-06 11:23:31 789

原创 ClassPathBeanDefinitionScanner初始化源码详解

本文解析了Spring中ClassPathBeanDefinitionScanner扫描器的初始化流程。该扫描器是AnnotationConfigApplicationContext的核心组件之一,负责扫描类路径下带有特定注解的类并注册为Bean。文章通过时序图和继承关系图,详细讲解了构造方法的调用链及核心初始化逻辑,包括注册器校验、默认过滤器设置(如@Component及其派生注解)、环境变量和资源加载器的配置。源码分析有助于理解Spring注解编程中组件扫描的底层机制。

2025-06-05 20:30:05 862

原创 加速你的Spring启动:揭秘 META-INF/spring.components 的秘密武器

Spring项目启动慢?试试META-INF/spring.components这个性能加速利器!传统@ComponentScan会扫描所有类路径,在大型项目中效率低下。Spring 5引入的类路径索引机制通过在编译时生成组件清单文件,让启动时直接加载已知组件,避免全量扫描。只需添加spring-context-indexer依赖,构建时自动生成该文件,即可将启动时间缩短20%-50%。注意确保第三方库包含索引文件,自定义注解需标记@Indexed。这种构建时优化策略投入小收益大,特别适合大型Spring。

2025-06-05 20:21:19 771

原创 Java元注解深度解析:掌握元注解

Java元注解:注解背后的控制者 摘要:元注解是Java中用于修饰其他注解的特殊注解,包含5种核心类型:@Target控制应用位置,@Retention管理生命周期,@Documented影响文档生成,@Inherited处理继承关系,@Repeatable允许重复使用。通过组合这些元注解,开发者可以创建强大的自定义注解,如字段验证、依赖注入等场景。典型应用包括定义运行时有效的验证注解(如@ValidEmail)或构建简易DI框架(使用@Component和@Autowired)。理解元注解是掌握Java注

2025-06-05 19:57:54 635

原创 AnnotatedBeanDefinitionReader初始化源码详解

本文解析了Spring框架中AnnotatedBeanDefinitionReader的源码实现,重点分析了读取器的初始化流程。通过时序图和类继承关系展示了该组件在AnnotationConfigApplicationContext中的核心作用。源码解析表明,读取器在构造过程中会校验注册表和环境对象,创建条件评估器ConditionEvaluator,并通过AnnotationConfigUtils注册多个关键的后处理器(如ConfigurationClassPostProcessor)。

2025-06-05 19:15:51 606

原创 Spring DefaultEventListenerFactory:事件监听器的核心工厂

Spring事件机制中的@EventListener注解和DefaultEventListenerFactory实现了高效的事件处理架构。DefaultEventListenerFactory作为核心工厂类,将标注@EventListener的方法转换为ApplicationListenerMethodAdapter实例,使方法成为事件监听器。相比传统实现ApplicationListener接口的方式,注解方式更简洁灵活,支持条件过滤、异步处理和事件链。开发者可以轻松创建自定义事件和监听器,通过Appli

2025-06-05 19:04:26 587

原创 Spring EventListenerMethodProcessor:事件监听器的幕后英雄

摘要 本文深入解析Spring框架中的EventListenerMethodProcessor组件,它作为实现事件驱动编程的关键机制,负责扫描并注册所有带有@EventListener注解的方法。文章详细介绍了该组件的生命周期、执行流程以及方法扫描原理,并通过一个完整案例展示如何定义自定义事件(如UserRegisteredEvent)、实现事件监听器(条件监听、多事件处理等),以及发布事件。案例包含用户注册和订单创建等业务场景,演示了Spring事件系统的灵活应用方式,为开发松耦合组件通信提供了实用参考。

2025-06-05 18:54:30 811

原创 Spring PersistenceAnnotationBeanPostProcessor:原理、应用与实战

本文深入解析了Spring框架中的PersistenceAnnotationBeanPostProcessor组件,它负责处理JPA相关的@PersistenceContext和@PersistenceUnit注解,实现EntityManager和EntityManagerFactory的自动注入。文章通过源码分析揭示其工作原理,并提供了一个完整的Spring整合JPA实战案例,包括实体类定义、Repository实现、Spring配置以及测试代码。关键点在于正确配置PersistenceAnnotatio

2025-06-05 16:02:28 639

原创 Spring CommonAnnotationBeanPostProcessor:核心原理与实战案例

摘要: CommonAnnotationBeanPostProcessor 是 Spring 处理通用注解(如 @Resource、@PostConstruct、@PreDestroy)的核心组件,支持依赖注入和生命周期回调。其工作流程包括扫描注解、注入依赖、执行初始化/销毁方法。通过示例展示了如何使用 @Resource 按名称或类型注入,以及 @PostConstruct/@PreDestroy 管理 Bean 生命周期。建议明确指定注入名称,保持生命周期方法轻量,并灵活搭配 XML 或 Java 配置

2025-06-05 15:54:04 668

原创 Spring AutowiredAnnotationBeanPostProcessor:自动装配的核心引擎

本文深入解析Spring框架中AutowiredAnnotationBeanPostProcessor的工作原理与应用。该处理器是实现@Autowired、@Value等注解依赖注入的核心组件,负责扫描注解、解析依赖关系并进行属性注入。文章通过源码分析其关键方法和工作流程,并演示了字段、构造器和方法三种注入方式。同时探讨了依赖冲突解决、可选依赖处理等特殊场景,以及如何通过继承该类实现自定义注解支持和流程扩展。最后总结了常见问题排查方法,帮助开发者更好地理解和应用Spring的IoC机制。

2025-06-05 15:39:48 905

原创 Spring ConfigurationClassPostProcessor工作原理与实践

Spring框架的核心组件ConfigurationClassPostProcessor负责解析配置类中的各种注解,将其转换为Bean定义。作为BeanFactory后置处理器,它的主要功能包括:扫描@Configuration类,处理@ComponentScan、@Bean、@Import等注解,以及生成CGLIB代理确保Bean单例行为。其工作流程从容器初始化开始,通过解析配置类并注册Bean定义,最终完成整个配置处理。源码分析展示了如何解析@Import注解及处理不同类型的导入类。实战案例演示了基础配

2025-06-05 14:36:27 669

原创 Spring XML Bean 定义继承详解

Spring XML Bean定义继承是一种配置层面的复用机制,通过parent属性指定父Bean,子Bean可继承父Bean的属性值、构造函数参数等配置。关键特性包括:1)仅继承配置元数据,不影响实例关系;2)支持抽象父Bean作为模板;3)子Bean可覆盖或新增配置。典型应用场景包括数据源配置、服务层公共事务管理以及框架集成。该机制能有效减少重复配置,提升可维护性,但需注意构造函数参数、依赖注入和作用域的继承规则。通过合理使用,可实现配置的高度复用和统一管理。

2025-06-04 19:54:16 925 1

原创 DefaultListableBeanFactory初始化源码详解

本文解析了Spring框架中DefaultListableBeanFactory的初始化过程,重点关注其在AnnotationConfigApplicationContext创建时的构造流程。通过时序图和类继承关系分析。核心逻辑包括:标记BeanNameAware等三个接口为忽略自动注入根据GraalVM环境检测结果选择实例化策略(Simple或Cglib)解析揭示了Spring容器的底层设计思想,包括依赖处理机制和环境适配策略。结合源码可深入理解Spring的核心初始化过程。

2025-06-04 16:54:01 910

原创 Spring BeanFactoryAware深度解析

本文深入解析Spring框架中的BeanFactoryAware接口机制与使用场景。该接口允许Bean访问创建它的BeanFactory,主要用于延迟加载Bean、动态获取多个实现类等框架扩展场景。通过支付路由器的实战案例,演示了如何安全使用该特性实现动态服务选择。文章强调在业务开发中应优先使用依赖注入,并指出注意事项:避免在构造函数中使用、谨慎操作getBean()、单元测试复杂度等。最后总结该接口适用于框架级开发和动态Bean查找等特殊场景,常规业务代码应限制使用范围。

2025-06-03 16:30:53 789

原创 Spring BeanClassLoaderAware回调深度解析:从原理到实战

摘要: BeanClassLoaderAware是Spring框架中用于让Bean获取自身类加载器的回调接口。它在Bean初始化阶段由容器自动注入类加载器,适用于动态加载类、访问资源文件等场景。核心原理是Spring在Bean生命周期中回调setBeanClassLoader方法,确保Bean与容器使用相同的类加载器,避免冲突。实战示例展示了如何通过该接口实现插件动态加载和资源访问,典型应用包括类路径资源加载、热部署插件等。该接口为Spring与Java类加载机制的无缝集成提供了关键支持。

2025-06-03 16:12:43 899

原创 Spring BeanNameAware回调详解:从原理到实战

本文深入解析 Spring 框架中的BeanNameAware回调接口,阐述其核心原理与应用场景。BeanNameAware通过setBeanName(String name)方法使 Bean 在初始化阶段获取自身在容器中的唯一标识(如 XML 配置的id或@Bean指定的名称),该回调发生在依赖注入之后、初始化方法之前,是 Spring Bean 生命周期中的关键扩展点。此外,文章强调了使用BeanNameAware的注意事项,如名称规则(单例 / 非单例 Bean 的命名差异)、回调顺序优先级,以及与

2025-06-03 16:12:05 901

原创 ClassPathXmlApplicationContext启动源码解析

本文介绍了Spring框架中的ClassPathXmlApplicationContext容器类,它是基于XML配置文件的IoC容器实现。主要内容包括: 基本用法:通过XML文件定义Bean并使用该类加载配置获取Bean实例 构造函数详解: 支持单/多配置文件加载 可指定父容器实现Bean继承 提供手动刷新控制选项 启动流程:从客户端调用到父类构造器逐层初始化的完整过程 该类是Spring传统XML配置方式的核心组件,通过灵活的构造函数和清晰的继承体系,为依赖注入提供了可靠的基础设施。

2025-05-29 10:27:45 890

原创 Spring基于XML的复合属性名注入实战详解

文章摘要: 本文介绍了Spring框架中复合属性注入的两种方式:链式属性注入和结构化注入。通过一个三层嵌套的实战案例,展示了如何在XML配置文件中实现对象间的多重嵌套关系。文章还提供了链式属性注入的技巧,并强调了配置优化策略,如组合式配置和混合式配置。最后,给出了最佳实践建议和常见问题排查步骤,帮助开发者更好地理解和应用复合属性注入。

2025-05-29 09:57:42 516

原创 Spring XML配置中的import标签详解:模块化配置的艺术

本文详细介绍了Spring框架中import标签的使用方法,涵盖其核心作用、语法规则、配置示例、实战场景及高级技巧。import标签支持模块化配置管理,可实现多环境切换、动态加载和第三方集成。文章提供了路径解析规则、典型错误示例、性能优化建议,并对比了不同Spring版本的兼容性差异。最后指出XML配置在遗留系统维护、动态配置等场景仍具价值,建议结合项目需求灵活运用import标签与Spring Boot配置管理。

2025-05-25 11:15:31 881

原创 使用c命名空间的Spring XML配置:简洁之道与传统对比

本文探讨了Spring框架中c命名空间的使用及其优势。传统XML配置方式存在代码冗余、维护成本高、可读性差和重构风险大等问题。c命名空间通过简化配置,提高了代码的密度和可维护性。文章详细介绍了c命名空间的激活和参数绑定模式,并通过电商订单系统的实战案例展示了其应用。此外,文章还对比了传统方式和c命名空间在技术维度和性能表现上的差异,并提出了混合配置策略建议。最后,文章展望了配置方式的演进趋势,指出在特定场景下XML配置仍具优势,并建议开发者根据项目需求选择合适的配置方式。

2025-05-25 10:46:54 776

原创 使用p命名空间的Spring XML配置:简洁之道与传统对比

本文详细探讨了Spring框架中传统XML配置与p命名空间的对比与应用。传统XML配置存在嵌套膨胀、冗长难读的问题,而p命名空间通过XML Schema的attribute扩展机制,简化了依赖注入的配置。文章分析了p命名空间的技术实现原理、语法细节,并通过结构化对比展示了其优势。此外,文章还探讨了p命名空间的扩展应用场景、性能与可维护性评估,并给出了现代Spring工程的实践建议。尽管注解配置已成为主流,但在特定场景下,p命名空间仍能显著提升XML配置的可维护性。建议根据项目需求和团队习惯选择合适的配置方式

2025-05-25 10:46:04 818

原创 Spring基于XML的属性注入:Null与空字符串的深度解析

本文深入探讨了Spring Framework中XML配置下null值与空字符串注入的核心差异。通过源码解析和实际测试案例,文章详细对比了两者在内存状态、XML配置方式、默认值处理、序列化表现、数据库映射和NPE风险等方面的不同。文章还提供了XML配置语法的详细示例,展示了空字符串和null值的注入方式,并通过JUnit测试验证了其行为。此外,文章还讨论了特殊场景的处理、底层机制解析,并给出了最佳实践建议和常见问题排查方法。总结指出,正确区分和使用null与空字符串注入是构建健壮Spring应用的基础,开发

2025-05-24 09:28:54 1150

原创 Spring基于XML的配置:深入理解idref元素

idref是Spring框架XML配置中的特殊元素,用于将容器中其他bean的标识符(id)以字符串形式注入,并在容器启动时验证目标bean是否存在。与常规属性注入不同,idref提供了引用验证机制,确保目标bean存在,避免运行时异常。其核心作用包括引用验证、配置自文档化、类型安全增强和容器启动预检。idref的配置方法包括属性注入和构造器注入,Spring容器在启动时会解析XML配置,检查目标bean的存在性,若验证失败则抛出异常。通过idref,开发者可以实现防御性配置,提前发现配置错误,并使配置文件

2025-05-24 09:28:29 551

原创 Spring基于XML的配置:Bean依赖注入深度解析

本文通过Mermaid图表和代码示例,详细介绍了Spring Framework 5.3.34版本中的依赖注入机制。文章首先解释了依赖注入的核心概念及其优势,随后展示了XML配置的基础依赖和构造器注入的三种形式(类型匹配、索引下标、参数名匹配)。接着,文章探讨了Setter方法注入的实现方式,并深入解析了Spring容器的依赖处理过程,包括Bean定义解析、依赖处理阶段、实例化顺序和注入执行阶段。此外,文章提供了一个完整的测试案例,涵盖了领域对象定义、XML配置和JUnit测试类。最后,文章总结了构造器注入

2025-05-23 09:12:42 1133

原创 Spring基于XML的配置:Bean实例化详解

本文介绍了Spring框架中Bean实例化的三种方式:构造器实例化、静态工厂实例化和实例工厂实例化。首先,通过pom.xml配置了Spring Context和JUnit依赖。接着,详细说明了每种实例化方式的实现步骤,包括XML配置、工厂类定义和测试代码。构造器实例化是默认方式,直接通过<bean>标签配置;静态工厂实例化通过factory-method指定静态方法创建Bean;实例工厂实例化则通过factory-bean和factory-method结合使用。最后,提供了完整的测试案例,展示了

2025-05-23 09:12:14 999

原创 Spring基于XML的配置:Bean别名详解

本文介绍了在Spring框架中通过XML配置Bean别名的方法及其实现机制。首先,环境准备需要在pom.xml中添加Spring和JUnit依赖。接着,详细说明了两种配置别名的方式:通过name属性或<alias>标签。通过测试案例验证了不同别名指向同一Bean实例的效果。文章还深入探讨了Spring中别名的存储机制,使用SimpleAliasRegistry维护别名映射,并通过DefaultSingletonBeanRegistry存储Bean实例。最后,总结了使用别名时的注意事项,如规范名称

2025-05-22 09:25:36 946

原创 Spring基于XML的配置:Bean作用域详解

本文介绍了Spring框架中Bean作用域的核心概念与配置实践。主要内容包括:1)Spring支持的5种作用域类型(singleton、prototype等)及其特性;2)XML配置方式示例,通过scope标签定义单例和原型Bean;3)测试验证方法,展示不同作用域Bean的生命周期差异;4)Maven依赖配置;5)最佳实践建议,分析不同场景下的适用模式;6)扩展思考如何自定义作用域。文章通过序列图、代码示例和对比测试,直观演示了Spring作用域的工作机制,为开发者合理选择作用域策略提供了实用指导。&lt

2025-05-22 09:24:34 720

原创 Spring基于XML的配置:Bean属性填充完全指南

本文介绍了如何在Spring框架中使用XML配置进行依赖注入,特别是针对复杂对象结构的属性注入。文章首先展示了DemoBean和DataSource类的定义,接着详细说明了如何通过XML配置文件为DemoBean注入基本类型、集合类型、数组、Properties类型以及引用类型的属性。随后,通过单元测试验证了配置的正确性。尽管现代Spring开发更倾向于使用注解和Java配置,但XML配置在大型项目和遗留系统中仍然具有重要地位。本文的示例帮助读者掌握了复杂对象属性的注入方式、集合类型的配置方法以及配置优化和

2025-05-21 11:54:37 599

原创 Spring基于XML的配置:beans与bean标签基础

本文介绍了Spring框架中通过XML配置文件进行依赖注入的基本方法。核心元素包括<beans>和<bean>,其中<beans>作为根元素包含所有bean定义,而<bean>标签则通过id和class属性定义Spring管理的对象。文章还提供了一个完整的XML配置示例,并展示了如何通过测试类加载和使用这些配置。尽管现代Spring应用更倾向于使用注解配置,但理解XML配置方式对于维护旧项目仍然至关重要。

2025-05-20 17:17:21 401

原创 Spring框架入门:Java开发者的春天来了!

想象一下,你正在建造一座房子。如果没有现成的工具和材料,你需要从零开始制作每一块砖、每一根梁,这将耗费大量时间和精力。Spring框架就像是Java开发者的"工具箱",它提供了各种现成的组件和解决方案,让你可以专注于建造"房子"的核心功能,而不是重复造轮子。Spring框架自2003年诞生以来,已经成为Java企业级开发的事实标准。根据2023年的开发者调查,超过60%的Java开发者在使用Spring或其衍生框架。这足以证明它的强大和普及程度!

2025-05-20 16:21:39 654

原创 深入解析Java PipedReader与PipedWriter:线程通信的字符管道

本文深入解析了Java中的PipedReader和PipedWriter,这两个类用于实现线程间的字符通信。文章首先介绍了其核心机制,包括环形字符缓冲区和线程同步机制。接着,详细分析了缓冲区的写入流程和读取流程,并通过一个实时日志处理的示例展示了生产者-消费者模型的实际应用。文章还探讨了底层的同步机制、异常处理机制,并提供了性能调优策略,如设置合理的缓冲区大小和批量读写优化。最后,文章对比了PipedReader/Writer与NIO Pipe的特性,并列举了常见问题排查方法,如死锁场景分析。通过这些内容,

2025-05-14 19:13:32 630

原创 深入解析Java管道流:PipedInputStream与PipedOutputStream的底层奥秘

Java中的PipedInputStream和PipedOutputStream是一对用于线程间通信的管道流,通过内存缓冲区实现数据传输。其核心设计基于环形队列,通过写入和读取指针管理数据存取,并使用synchronized和wait/notify机制确保线程同步。管道流适用于多线程环境,但需注意避免死锁和数据丢失问题。优化技巧包括调整缓冲区大小和批量读写操作。正确使用管道流可以构建高效的线程通信系统,但需确保在不同线程中使用读写端,并及时关闭资源。

2025-05-14 19:13:02 591

原创 深入解剖Java对象序列化:ObjectOutputStream/ObjectInputStream完全指南

Java对象序列化通过ObjectOutputStream和ObjectInputStream实现对象的持久化和重建。序列化过程包括写入魔数、版本号、对象元数据和字段数据,最终以TC_ENDBLOCKDATA标记结束。反序列化时,系统会校验魔数和版本号,通过类加载器查找Class对象,并递归填充字段数据。自定义序列化允许开发者完全控制序列化过程,而serialVersionUID则用于版本兼容性控制。尽管序列化机制强大,但存在安全漏洞,建议使用白名单验证和避免反序列化不可信数据。随着技术的发展,JSON和P

2025-05-13 18:52:36 1236

原创 Java I/O 的魔法衣架:深度剖析FilterInputStream与FilterOutputStream

Java的I/O系统通过装饰器模式(Decorator Pattern)实现了灵活的功能扩展,核心类FilterInputStream和FilterOutputStream扮演了关键角色。FilterInputStream通过包装底层流,提供了缓冲、数据转换等功能,典型子类如BufferedInputStream和DataInputStream分别实现了缓冲和数据类型转换。FilterOutputStream则用于输出流的装饰,如PrintStream和CipherOutputStream。装饰器模式允许在

2025-05-13 18:52:17 884

原创 深入剖析Java FileReader和FileWriter的底层原理

本文深入剖析了Java中FileReader和FileWriter的底层原理,重点分析了字符流与字节流的本质区别、类继承结构、编码转换机制以及性能优化建议。FileReader继承自InputStreamReader,通过StreamDecoder将字节流转换为字符流,而FileWriter继承自OutputStreamWriter,使用StreamEncoder将字符流编码为字节流。文章还探讨了编码问题、异常处理最佳实践以及高级应用场景,如大文件差异对比和二进制文件混合处理。最后,提供了JDK版本演进的对

2025-05-12 17:14:19 980

原创 深入剖析Java的DataInputStream和DataOutputStream

网络传输场景优先使用跨平台数据交换注意字节序配合缓冲流提升性能保持读写顺序严格一致处理异常时要关闭资源通过掌握这些底层细节,开发者可以更好地驾驭Java的数据持久化和网络传输,写出高效可靠的IO代码。

2025-05-12 17:13:46 600

原创 进阶篇:校验框架性能调优与架构优化实战

通过综合运用缓存机制、并行处理、架构解耦等优化策略,可使校验性能提升300%以上。实际优化时需注意:1. 根据业务场景选择合适的优化组合2. 建立完善的性能测试基准3. 平衡代码可维护性与性能需求4. 定期进行架构评审和优化迭代

2025-05-11 10:38:23 399

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除