跟Manus聊聊Bean生命周期设计哲学[From Manus]

news/2025/9/28 17:02:09/文章来源:https://www.cnblogs.com/xtkyxnx/p/19117157

跟Manus聊聊Bean生命周期设计哲学[From Manus]

Posted on 2025-09-28 17:00  吾以观复  阅读(0)  评论(0)    收藏  举报

关联知识库:跟Manus聊聊Bean生命周期设计哲学[From Manus]

Mind Roadmap

  • Bean生命周期设计哲学
  • “零干预”下的Bean生命周期默认行为
  • Bean生命周期:开发者干预能力(扩展点)完整指南

参考资料

  • Customizing the Nature of a Bean
  • Container Extension Points
  • Customizing Configuration Metadata with a BeanFactoryPostProcessor

Bean生命周期设计哲学

核心设计思想一:分离关注点(Separation of Concerns)

Spring的设计者将一个复杂对象的创建过程,精心地拆分成了几个逻辑上独立且关注点不同的阶段。这就像盖房子,你不会把和水泥、砌墙、装修、通电通水混在一起做,而是分成地基、主体结构、内部装修等独立步骤。

  1. 实例化 (Instantiation) - “诞生”

    • 关注点“我是谁?” 这一步的唯一目标就是调用构造函数,在内存中创造出一个“裸露”的对象实例。它只关心对象的“出生”,不关心它需要什么(依赖)或能做什么(能力)。
    • 为什么分离:将对象的创建(new)和其依赖的配置(setter)解耦。这使得Spring可以在对象创建后,但在它被使用前,有机会做很多事情,比如决定是否要继续配置它。
  2. 属性填充 (Population) - “喂养”

    • 关注点“我需要什么?” 这一步的目标是满足Bean的依赖关系。Spring像一个保姆,把这个Bean所声明需要的其他Bean(依赖)和配置值(属性)“喂”给它。
    • 为什么分离:依赖注入是Spring的核心。将它独立出来,使得依赖关系的管理变得非常清晰和自动化。对象本身不需要关心去哪里找依赖,只管声明即可。
  3. 初始化 (Initialization) - “成年与赋能”

    • 关注点“我能做什么?” 此时,对象已经“吃饱喝足”(依赖已满足),但可能还不具备服务能力。初始化阶段就是让Bean执行其内部逻辑,为正式工作做最后的准备。比如,数据库连接池需要在此阶段建立连接,缓存需要加载初始数据。
    • 为什么分离:这是一个关键的“准备就绪”阶段。如果把初始化逻辑放在构造函数里,那么当构造函数执行时,对象的依赖(如DataSource)可能还没有被注入,这会导致空指针异常。只有在属性填充之后,才能安全地执行依赖于这些属性的初始化逻辑。 这就是为什么必须有独立的初始化阶段。
  4. 销毁 (Destruction) - “身后事”

    • 关注点“如何优雅地离开?” 这一步的目标是释放Bean占有的资源,确保系统不会因为它的消亡而产生资源泄漏或其他副作用。
    • 为什么分离:与初始化对应,销毁逻辑也需要一个明确的、独立于垃圾回收(GC)的阶段来执行,以保证资源的有序释放。

小结:这种分离,使得每个阶段的职责都非常单一和明确,极大地降低了复杂性,并为后续的扩展提供了清晰的切入点。


核心设计思想二:渐进式构建与全面开放(Progressive Construction & Universal Extensibility)

“几乎在整个链路上都有可扩展的点”。这并非偶然,而是Spring框架设计哲学的直接体现:“我们提供一个强大的默认流程,但你在任何一步都可以介入和改变它。”

这背后的思想是:

  1. 默认情况下的“零侵入”:对于一个简单的Bean,开发者可以什么都不用做,Spring会自动完成实例化、属性填充、初始化等所有工作。你只需写一个纯净的POJO(Plain Old Java Object),这大大降低了使用门槛。

  2. 提供“钩子”以应对复杂性:现实世界的应用是复杂的。Spring的设计者预见到开发者会有各种各样的定制需求,因此在每个阶段的关键节点前后都设置了“钩子”(Hooks),也就是我们说的扩展点。

    • 为什么是“前后”? 这种“环绕式”的扩展点设计(如BeanPostProcessorBeforeAfter方法)提供了最大的灵活性。
      • Before钩子:允许你在Spring执行默认操作之前进行干预。比如,在初始化之前修改Bean的某个属性。
      • After钩子:允许你在Spring完成默认操作之后进行加工。最典型的例子就是AOP,Spring完成了Bean的初始化,然后BeanPostProcessor的后置处理钩子介入,将这个健康的原始Bean包装成一个功能更强大的代理Bean。
  3. 将框架自身功能建立在扩展点之上:Spring的许多核心功能,如AOP、事务管理(@Transactional)、配置注入(@Autowired等,并不是硬编码在生命周期流程中的“特权代码”。相反,它们本身就是通过实现这些公共的扩展点(主要是BeanPostProcessorBeanFactoryPostProcessor)来完成的。

    • 这带来的巨大好处是
      • 公平性:框架自身的功能和开发者的自定义功能,使用的是同一套扩展机制,大家都是“一等公民”。
      • 可学习性:通过学习Spring如何利用这些扩展点来实现AOP,开发者也能学会如何利用它们来实现自己的框架级功能。
      • 模块化:框架的功能被解耦成一个个独立的Processor,使得系统更加清晰和可维护。

总结:设计哲学的回答

所以,回到您的问题:“Bean生命周期为什么要这样设计?其思想是什么?”

答案是:

Spring Bean的生命周期被设计成一个关注点分离的、渐进式的构建流程。它将一个复杂对象的诞生到消亡,拆解为实例化、属性填充、初始化、销毁等逻辑独立的阶段。这样做首先保证了对象构建过程的健壮性和逻辑清晰性(例如,确保在执行初始化前依赖已注入)。

更重要的是,Spring秉持开放扩展的设计哲学,在每一个阶段的关键节点都提供了“钩子”(扩展点)。它不仅允许开发者介入以满足定制化需求,甚至将框架自身的核心功能(如AOP)也构建在这套开放的扩展体系之上。这种设计使得Spring既能为简单应用提供“零侵入”的易用性,又能为复杂系统提供“无所不能”的强大灵活性。

这套设计思想,是Spring框架能够保持如此强大生命力和适应性的根本原因。

“零干预”下的Bean生命周期默认行为

假设我们有一个最简单的Bean:

@Component
public class SimpleService {@Autowiredprivate AnotherService anotherService; // 一个依赖private String name = "Default Name"; // 一个普通属性// 没有自定义构造函数,将使用默认的无参构造函数
}

1. 实例化 (Instantiation)

  • 默认动作

    1. Spring容器启动时,会扫描到@Component注解,为SimpleService创建一个BeanDefinition(设计图纸)。
    2. 当需要创建SimpleService的实例时,Spring会发现这个类没有定义任何构造函数,于是默认调用其无参构造函数 (new SimpleService()) 来创建一个对象实例。
    3. 这个实例被创建出来后,它的anotherService字段是nullname字段是"Default Name"
  • 此时发生了什么:一个“空的”、“未配置的”Java对象被创建出来了。

2. 属性填充 (Population)

  • 默认动作

    1. Spring会检查SimpleService实例的所有字段和方法,寻找依赖注入的注解。
    2. 它会发现anotherService字段上标注了@Autowired
    3. 于是,Spring会去容器中查找一个类型为AnotherService的Bean。
    4. 找到后,通过Java的反射机制(Field.set(),将AnotherService的实例赋值给SimpleService实例的anotherService字段。
    5. 对于没有注解的普通字段(如name),Spring不会做任何操作,它将保持在实例化阶段赋予的默认值。
  • 此时发生了什么:Bean的“依赖”被自动满足了。这是Spring IoC核心价值的体现,即使你不写任何扩展代码,也能享受到依赖注入的好处。

3. 初始化 (Initialization)

这是变化最明显的阶段。因为我们没有提供任何扩展点,所以大部分步骤都会被“优雅地跳过”。

  • 默认动作

    1. 检查Aware接口:Spring会检查SimpleService是否实现了BeanNameAware, BeanFactoryAware等接口。发现没有,直接跳过
    2. 执行BeanPostProcessor前置处理:Spring会遍历所有内部注册BeanPostProcessor(即使我们没自定义,Spring自己也有一些),并调用它们的postProcessBeforeInitialization方法。但对于我们这个简单的Bean,这些内部处理器通常也无事可做,所以这个过程很快就过去了。
    3. 执行初始化方法:Spring会检查SimpleService中是否有@PostConstruct注解的方法,或者是否实现了InitializingBean接口。发现没有,直接跳过
    4. 执行BeanPostProcessor后置处理:Spring再次遍历所有内部的BeanPostProcessor,调用postProcessAfterInitialization方法。这是一个关键点:即使我们没有写AOP,Spring内部的一些处理器(比如处理@Async@Scheduled注解的)也可能会在这里工作。但对于我们这个纯净的Bean,同样,它们通常什么也不做。
  • 此时发生了什么:Bean已经“准备就绪”并被放入了单例池中,可以被其他任何需要它的地方注入和使用了。虽然初始化阶段看起来执行了很多检查,但因为没有匹配的扩展点,所以几乎是“空跑”了一遍流程。

4. 使用 (In Use)

  • 默认动作SimpleService的单例Bean安静地待在Spring容器的“单例池”(一个Map)中。当有其他Bean通过@Autowired需要它时,Spring就从这个池子里把它拿出来,传递过去。

5. 销毁 (Destruction)

  • 默认动作
    1. 当Spring容器关闭时(例如,主程序退出),它会准备销毁所有单例Bean。
    2. 检查销毁方法:Spring会检查SimpleService中是否有@PreDestroy注解的方法,或者是否实现了DisposableBean接口。发现没有,直接跳过
    3. 最终,这个SimpleService对象会失去所有引用,等待Java垃圾回收器(GC)在未来的某个时间点回收其内存。Spring不会对它做任何额外的清理工作。

总结

在“零干预”的情况下,Spring的生命周期管理依然提供了两大核心价值:

  1. 自动化的对象创建:你不需要自己 new 对象,Spring会帮你完成。
  2. 自动化的依赖注入:你不需要手动设置依赖,Spring会通过 @Autowired 等注解帮你自动“装配”。

整个流程就像一个高度自动化的工厂,即使你不安插任何自定义的工序,它依然能按照默认的蓝图,生产出“基础款”的产品(一个依赖完整、可直接使用的Bean)。而所有的扩展点,都是为了让你有机会在这条流水线上,根据自己的需求,生产出功能更强大的“定制款”产品。

好的,我完全明白您的要求了。非常感谢您把模板粘贴出来,这能确保我精确地按照您最满意的格式进行补充。

核心任务是:保持您所欣赏的“三分类”文档结构和风格不变,在此基础上,将关于BeanDefinition的扩展点作为一个更早的、独立的阶段补充进去。

以下是为您精心准备的、可以直接用于记录的最终版本。


Bean生命周期:开发者干预能力(扩展点)完整指南

我们将开发者可以干预Bean生命周期的能力,按照其“使用目的”和“影响范围”,归纳为以下几个层次。

零阶段:Bean“图纸”设计与修改 (框架级/高级定制)

这个阶段发生在任何Bean实例被创建之前。它不处理Bean的实例对象,而是直接处理用于定义Bean的“施工图纸”——BeanDefinition

阶段 扩展点/方式 核心作用 使用建议和场景
Bean定义加载后,实例化前 BeanFactoryPostProcessor 读取并修改所有Bean的“图纸”(BeanDefinition)。它能访问到整个Bean工厂的配置元数据,并在容器实例化任何Bean之前,对这些元数据进行全局性的修改。 非常强大的高级扩展点,谨慎使用。它能从根本上改变Bean的行为。主要用于:
- 动态修改Bean定义:例如,根据环境动态地将某个Bean的作用域从singleton改为prototype,或者替换其Class定义。
- 注册额外的Bean:以编程方式向容器中动态添加新的BeanDefinition
- 属性占位符解析:Spring自身处理@Value("${...}")占位符的功能,就是通过一个名为PropertySourcesPlaceholderConfigurerBeanFactoryPostProcessor实现的。

类别一:针对单个Bean的“内部”逻辑干预 (最常用,业务开发者首选)

这类扩展点允许您在Bean的生命周期中,为特定的、单个Bean添加自定义的业务逻辑。

阶段 扩展点/方式 核心作用 使用建议和场景
实例化后 / 属性填充 @Autowired, @Resource, @Value 自动依赖注入和配置值注入。这是Spring IoC的核心,无需手动干预,Spring会自动完成。 这是最常用的属性填充方式。您只需声明依赖,Spring会自动找到并注入。无需额外干预,除非您需要非常特殊的属性处理逻辑(见类别二)。
初始化 @PostConstruct 在Bean所有属性被填充后,执行一次性初始化逻辑 强烈推荐。用于执行Bean启动时必须完成的业务逻辑,如:
- 数据库连接池初始化
- 缓存数据预加载
- 启动后台线程或定时任务
- 验证Bean的配置是否正确
InitializingBean (接口) @PostConstruct功能相同,但不推荐,因为它与Spring框架耦合。 仅在无法使用注解的旧项目或特殊兼容场景下考虑。
init-method (XML/@Bean属性) 通过配置指定初始化方法。 当您无法修改Bean的源代码时使用,例如集成第三方库的类。
销毁 @PreDestroy 在Bean被销毁前,执行资源清理逻辑 强烈推荐。用于释放Bean占用的资源,确保应用优雅关闭,如:
- 关闭数据库连接
- 停止后台线程或线程池
- 清理临时文件
- 释放网络端口
DisposableBean (接口) @PreDestroy功能相同,但不推荐,因为它与Spring框架耦合。 仅在无法使用注解的旧项目或特殊兼容场景下考虑。
destroy-method (XML/@Bean属性) 通过配置指定销毁方法。 当您无法修改Bean的源代码时使用,例如集成第三方库的类。

关于销毁方法的使用频率:
这取决于Bean是否持有外部资源。

  • 如果Bean只包含内存数据和逻辑,不持有外部资源:确实,销毁方法可能不那么重要,因为JVM关闭时会回收内存。
  • 如果Bean持有外部资源(如数据库连接、文件句柄、网络端口、线程池等):那么销毁方法就至关重要。不释放这些资源可能导致资源泄漏、端口占用、数据不一致等问题,尤其是在长时间运行的服务器应用中。即使应用关闭,也需要确保这些外部资源被正确释放。

类别二:针对所有Bean的“外部”增强干预 (框架/中间件开发者常用)

这类扩展点允许您对容器中所有(或符合条件的)Bean进行统一的、横切的增强或修改。这是Spring实现AOP等高级功能的基础。

阶段 扩展点/方式 核心作用 使用建议和场景
实例化前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation() 在Bean实例化之前,完全替换或阻止默认的实例化过程。如果此方法返回一个非null对象,Spring将直接使用它,跳过后续的实例化和属性填充。 非常高级的用法。适用于需要完全控制Bean创建过程的场景,例如:
- 从缓存中获取Bean实例
- 实现自定义的单例模式
- 动态生成代理对象(在实例化阶段就介入)
实例化后 / 属性填充前 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation() 在Bean实例化后,但在属性填充之前,决定是否继续属性填充。如果返回false,则跳过属性填充。 较少直接使用。通常用于特殊场景,例如:
- 某些Bean的属性不需要Spring自动填充,而是通过其他方式手动设置。
属性填充 InstantiationAwareBeanPostProcessor.postProcessProperties() 在Spring自动填充属性之前,允许您检查、修改或添加属性值 高级用法。适用于需要动态调整属性注入的场景,例如:
- 根据环境或运行时条件,动态修改@Value注入的值。
- 实现自定义的属性解析逻辑。
初始化前后 BeanPostProcessor.postProcessBeforeInitialization() 在Bean的任何初始化方法(@PostConstruct等)执行之前,对Bean进行修改或包装 常用。可以在Bean初始化前进行通用处理,例如:
- 统一的配置检查
- 注入一些非Spring管理的资源
- 对Bean进行初步的包装或代理(但AOP主要在后置处理)
BeanPostProcessor.postProcessAfterInitialization() 在Bean所有初始化方法执行完毕后,对Bean进行最终的修改或包装 最强大、最常用的BeanPostProcessor方法Spring AOP就是在此处实现的。它会返回一个代理对象来替换原始Bean。场景包括:
- 实现AOP:为Bean创建代理,织入事务、日志、安全等横切逻辑。
- 自定义注解处理:扫描Bean上的自定义注解,并根据注解内容对Bean进行增强或注册。
- 动态代理:为特定Bean创建代理,实现自定义的拦截逻辑。
销毁前 DestructionAwareBeanPostProcessor.postProcessBeforeDestruction() 在Bean被销毁前,执行通用的清理逻辑 较少直接使用。通常用于框架层面的统一资源清理,例如:
- 记录Bean销毁日志
- 统一释放某些共享资源

类别三:与Spring容器底层交互干预 (特殊场景使用)

这类扩展点允许Bean获取Spring容器自身的引用,从而可以编程方式与容器进行交互。

阶段 扩展点/方式 核心作用 使用建议和场景
初始化前 Aware系列接口
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- ApplicationContextAware
- EnvironmentAware
- ResourceLoaderAware
- MessageSourceAware
- ApplicationEventPublisherAware
让Bean“感知”并获取到Spring容器的特定资源或上下文。Spring会在初始化阶段,自动调用这些接口的方法,将相应的资源注入给Bean。 谨慎使用,避免过度耦合。只有当您的Bean确实需要访问容器的特定功能时才使用。例如:
- ApplicationContextAware:当Bean需要编程方式获取其他Bean(通过applicationContext.getBean()),或者发布应用事件时。
- BeanNameAware:当Bean的内部逻辑需要知道它在容器中的名称时(例如,用于日志记录或特定配置查找)。
- BeanFactoryAware:与ApplicationContextAware类似,但提供了更底层的BeanFactory访问能力。

关于Aware接口和BeanPostProcessor的区别:

  • Aware接口

    • 目的:让Bean自身获取到它所运行的容器环境信息
    • 作用对象单个Bean
    • 比喻:就像一个员工(Bean)入职时,公司(容器)告诉他:“这是你的工牌(BeanName),这是你的部门(BeanFactory/ApplicationContext)。”
  • BeanPostProcessor

    • 目的拦截和修改/增强容器中“所有”或“符合条件”的Bean
    • 作用对象所有Bean
    • 比喻:就像一个质检员(BeanPostProcessor),在产品(Bean)出厂前和出厂后,对产品进行检查、包装或功能升级(如AOP)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Software Crisis and Complexity

Software Crisis and ComplexityPosted on 2025-09-28 17:00 吾以观复 阅读(0) 评论(0) 收藏 举报关联知识库:Software Crisis and Complexity软件危机与复杂性:工程思维的诞生背景 核心要点 第一次软件危机(1…

Foojay 播客 #71:与 James Gosling 一起庆祝 Java 诞生 30 周年

Foojay 播客 #71:与 James Gosling 一起庆祝 Java 诞生 30 周年Posted on 2025-09-28 17:00 吾以观复 阅读(0) 评论(0) 收藏 举报关联知识库:Foojay 播客 #71:与 James Gosling 一起庆祝 Java 诞生 30 周年htt…

# Stack Overflow 2011-2019开发者调查报告:技术生态演进史

# Stack Overflow 2011-2019开发者调查报告:技术生态演进史Posted on 2025-09-28 17:00 吾以观复 阅读(0) 评论(0) 收藏 举报关联知识库:# Stack Overflow 2011-2019开发者调查报告:技术生态演进史Stack Ove…

中国建设行业峰会官方网站改图网站

一、引言 在信息爆炸的时代,网络上蕴含着海量的数据。如果我们想要获取特定的信息,手动从网页上复制粘贴显然效率极低。这时,Web 爬虫就派上了用场。Web 爬虫是一种自动获取网页内容的程序,它可以模拟人类在浏览器中的操作,快速地抓取网页上的数据。本文将带领大家使用 Py…

langgraphjs-gen-ui-examples

langgraphjs-gen-ui-examples https://github.com/langchain-ai/langgraphjs-gen-ui-examplesLangGraph Generative UI ExamplesThis repository contains a series of agents intended to be used with the Agent Cha…

2025 年节能咨询公司最新权威推荐排行榜:覆盖工业 / 建筑 / 数据中心等领域 TOP5 优质企业综合测评与选型指南发电厂/燃气/全域增效/服务器节能公司推荐

在 “双碳” 目标深化推进的当下,企业对节能咨询服务的需求日益迫切,但市场现状却让企业面临诸多困扰。部分服务商技术单一,仅能解决局部能耗问题,无法实现全流程节能优化;有些服务商过度宣传,实际节能效果与承诺…

微算法科技(NASDAQ MLGO)探索全同态加密与安全多方计算融合,开启区块链隐私执行新时代

随着区块链应用场景不断拓展,跨分片复杂合约的隐私保护需求日益凸显。传统区块链技术在处理此类合约时,难以兼顾数据隐私与功能实现。交易数据和合约执行细节常以明文形式存储和处理,易导致敏感信息泄露。微算法科技…

杭州仪器网站制作海外运营是做什么的

戳蓝字“CSDN云计算”关注我们哦!2019年7月9日,IBM史上最大的一笔收购案终于尘埃落定,IBM以每股现金190.0美元,完成对红帽所有已发行和流通在外普通股的收购交易,总股本价值约340亿美元。至此,红帽这家全球…

国产SUB-1G芯片DP4363F支持119-1050mhz超低功耗 - 动能世纪

DP4363是一款高性能、低电流的收发器,覆盖了从119MHZ到1050MHz的频段。它是系列完整发射器、接收器和收发器产品中的组成部分,适用于各种广泛的应用场景。该设备具有卓越的灵敏度,达到-126dBm,同时实现了极低的运行…

上海网站分站建设成都市建设质监站网站

【问题描述】 第200题 岛屿数量 给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外&#xf…

做设计用图片的网站为什么不做网站做公众号

有win10用户说他在更新完系统后,在切换输入法的时候发现竟然切换不了无法切换,都不知道该怎么办了,这个小问题也是常有的,那么win10更新后不能切换输入法怎么办呢,下面小编给大家分享win10输入法切换不了的解决方法。 …

2025 年棕刚玉源头厂家最新推荐排行榜:TOP 级生产厂家原料与烧结工艺权威解析,助力企业精准选购一级棕刚玉/棕刚玉磨料/优质棕刚玉/棕刚玉喷砂废料回收厂家推荐

在工业研磨、表面处理等关键领域,棕刚玉磨料的品质直接决定生产效率与成品精度,是下游企业保障生产质量的核心要素。当前市场中,棕刚玉厂家数量繁杂,部分厂家存在原料把控不严、烧结工艺落后等问题,导致产品杂质超…

杀疯了!GitHub 发布 Copilot CLI!!!

大家好,我是R哥。 今年 AI 编程赛道真是大乱斗啊,特别是面向「终端」的 AI 编程工具,自从 Anthropic 的 Claude Code CLI 问世以来,XX CLI 层出不穷:Google - Gemini CLI Cursor CLI OpenAI - CodeX CLI ……如果…

2025 年无尘金刚砂源头厂家最新推荐排行榜:权威精选企业产能与品质深度解析无尘金刚砂材料/无尘金刚砂批发/无尘金刚砂喷砂厂家推荐

在工业研磨、表面处理等核心领域,无尘金刚砂的品质直接决定加工精度、生产效率及工件成品质量,是众多企业生产环节中不可或缺的关键磨料。当前市场上,无尘金刚砂厂家数量众多,但产品质量差异显著,部分厂家因原料劣…

langgraph-genui

langgraph-genui https://github.com/fanqingsong/langgraph-genuiLangGraph GenUI 微服务架构这是一个基于 LangGraph 的微服务架构项目,包含智能体服务和前端对话界面两个独立的微服务。项目结构langgraph-genui/ ├…

外国网站邀请做编辑广州做网站找酷爱网络

开源项目专题系列(八)1.开源项目名称:magpie_fly2.github地址:https://github.com/wuba/magpie_fly3.简介:magpie_fly 是58集体出品组件库,统一管理日常开发中的基础组件及高阶组件,并提供了相对友好的方式介绍组件的具…

中国住房和城乡建设厅网站美食教做网站

过了面试,后面的在线测评还会刷人吗?完全有可能刷,如果不是为了刷,何必要给你做线上测评,我说的有道理不? 好吧,说到为什么在线测评要刷人,怎么刷? 怎么才能确保不被刷&…

web服务器配置步骤有哪些?如何建立一个web服务器

建立一个 Web 服务器 并配置它,是托管网站、应用程序或服务的基础任务。以下是完整的 Web 服务器配置步骤,涵盖从准备服务器到部署网站的流程,包括选择技术栈、安装软件、配置安全性和优化性能。1. 准备工作 1.1 选…