当前位置: 首页 > news >正文

SpringBoot下类加入容器的几种方式

SpringBoot下类加入容器的几种方式

在 Spring Boot 中,类加入容器的方式不仅多样,而且每种方式都有其特定的使用场景。以下是几种常见的将类加入 Spring 容器的方法及其适用场景:

1. 使用 @Component 及其派生注解

使用场景:当开发者希望以最小的配置将某个类自动注册为 Spring 管理的 Bean 时,可以使用 @Component 注解。对于分层架构的应用程序,推荐使用 @Component 的派生注解,如 @Controller@Service@Repository,它们分别用于标记控制器层、业务逻辑层和服务层的组件。这种方式适用于大多数情况下,特别是当你希望利用 Spring 的自动扫描机制来简化配置时。

@Component
public class MyComponent {// 组件逻辑...
}

为了确保这些带有注解的类能够被 Spring 发现并注册,通常需要在启动类或配置类中添加 @ComponentScan 注解,并指定要扫描的基础包路径。

2. 使用 @Configuration + @Bean

使用场景:当需要创建复杂的 Bean 或者 Bean 的初始化逻辑较为复杂时,推荐使用 @Configuration + @Bean 的组合。这种方式允许通过 Java 配置类的形式定义 Bean,提供了更强大的控制力和灵活性。例如,当需要根据不同的条件创建不同类型的 Bean 实例,或者需要在 Bean 创建过程中执行额外的初始化操作时,这种方法尤为有用。

@Configuration
public class MyConfig {@Beanpublic MyService myService() {return new MyServiceImpl();}
}

此外,@Bean 注解还可以接受多个参数,比如 name 用于指定 Bean 的名称,initMethoddestroyMethod 分别用于指定初始化和销毁方法等。

3. 使用 @Import 注解

使用场景@Import 注解主要用于导入其他配置类或普通类到 Spring 容器中。它特别适合于框架级别的扩展,或者当需要从外部模块引入 Bean 时。通过实现 ImportSelector 接口,可以根据条件动态选择要导入的类;而通过实现 ImportBeanDefinitionRegistrar 接口,则可以自定义注册 Bean 的逻辑。

@Import(MyConfig.class)
public class Application {// ...
}

4. 实现 BeanDefinitionRegistryPostProcessor

使用场景:对于需要在 Bean 定义加载完成后对其进行修改或添加新的 Bean 定义的情况,可以通过实现 BeanDefinitionRegistryPostProcessor 接口来实现。这种方式通常用于框架级别的扩展,因为它允许在 Bean 定义加载完成后对其进行修改或添加新的 Bean 定义。

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {// 手动注册 Bean 定义AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(MyComponent.class).getBeanDefinition();registry.registerBeanDefinition("myComponent", beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {// 可选实现}
}

5. 使用 FactoryBean 接口

使用场景:当需要创建的对象不能直接通过构造函数或静态工厂方法创建时,可以考虑使用 FactoryBean 接口。这为创建复杂的对象提供了一种途径,尤其是在对象的创建过程涉及到多个步骤或依赖项的情况下。

public class MyFactoryBean implements FactoryBean<MyComponent> {@Overridepublic MyComponent getObject() throws Exception {return new MyComponent();}@Overridepublic Class<?> getObjectType() {return MyComponent.class;}@Overridepublic boolean isSingleton() {return true;}
}

6. 动态注册 Bean

使用场景:有时候,应用程序可能需要在运行时根据某些条件动态地向容器中注册 Bean。这可以通过获取 ApplicationContext 的引用,然后使用 BeanDefinitionRegistryAutowireCapableBeanFactory 来实现。例如,在处理动态加载模块或插件化架构时,这种技术非常有用。

@Autowired
private ConfigurableApplicationContext applicationContext;public void registerBeanAtRuntime() {DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();beanFactory.registerSingleton("myDynamicComponent", new MyComponent());
}

7. 使用 @Conditional 注解

使用场景@Conditional 注解允许根据某些条件来决定是否将某个 Bean 注册到容器中。这对于构建支持多环境的应用程序非常重要,因为可以根据环境变量、操作系统类型或其他条件来有条件地注册 Bean。例如,当某个特性仅在特定环境中启用时,可以使用 @ConditionalOnProperty 来控制 Bean 的注册。

@Bean
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public MyFeature myFeature() {return new MyFeature();
}

8. 使用 @ImportResource 注解

使用场景:如果项目中已经存在 XML 配置文件,可以使用 @ImportResource 注解来导入这些 XML 文件中的 Bean 定义。这种方式可以让开发者逐步迁移旧有的基于 XML 的配置到 Spring Boot 的注解驱动配置中,同时保持现有系统的兼容性。

@Configuration
@ImportResource("classpath:beans.xml")
public class MyConfig {// 其他配置...
}

9. 使用 @Enable* 注解

使用场景:Spring 提供了一系列以 @Enable 开头的注解,如 @EnableScheduling@EnableTransactionManagement 等,它们可以用来启用特定的功能或特性。这些注解通常会自动配置相关的基础设施 Bean,从而简化了开发者的配置工作。例如,当需要启用定时任务调度功能时,可以使用 @EnableScheduling 注解。

@Configuration
@EnableScheduling
public class SchedulingConfig {// 配置调度任务...
}

总结

综上所述,Spring Boot 提供了多种方式来将类加入到容器中,每种方式都有其特定的使用场景。选择合适的 Bean 注册方式不仅可以提高开发效率,还能增强应用程序的灵活性和可维护性。开发者应根据具体的应用需求和个人偏好,灵活选择最适合的方式来管理 Bean 的生命周期和依赖关系。例如,在构建微服务架构时,可能会更多地依赖于 @Component@Configuration + @Bean 的组合;而在进行框架扩展或插件化开发时,则可能更倾向于使用 @Import 或实现 BeanDefinitionRegistryPostProcessor 接口。此外,随着 Spring Boot 不断发展,新的特性和工具也在不断涌现,开发者应当持续关注官方文档和技术社区,以便及时掌握最新的实践和技术趋势。

相关文章:

SpringBoot下类加入容器的几种方式

SpringBoot下类加入容器的几种方式 在 Spring Boot 中&#xff0c;类加入容器的方式不仅多样&#xff0c;而且每种方式都有其特定的使用场景。以下是几种常见的将类加入 Spring 容器的方法及其适用场景&#xff1a; 1. 使用 Component 及其派生注解 使用场景&#xff1a;当开…...

【Mysql】忘记Root密码后如何不影响数据进行重置密码

方法一&#xff1a;通用方法--启动时跳过权限表 1> 停止数据库 以管理员方式打开cmd&#xff01;&#xff01; C:\Users\Administrator>net stop mysql MySQL 服务正在停止.. MySQL 服务已成功停止。 2> 启动时跳过权限表 mysqld --console --skip-grant-tables -…...

宝塔内设置redis后,项目以及RedisDesktopManager客户端连接不上!

项目展现问题&#xff1a; Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to xxx.宝塔外链.ip.xxxx:6379 redis客户端连接失败&#xff1a; 1、宝塔中确认redis端口已放行 2、修改redis的配置 bind&#x…...

一文了解模式识别顶会ICPR 2024的研究热点与最新趋势

简介 对模式识别研究领域前沿方向的跟踪是提高科研能力和制定科研战略的关键。本文通过图文并茂的方式介绍了ICPR 2024的研究热点与最新趋势&#xff0c;帮助读者了解和跟踪模式识别的前沿研究方向。本推文的作者是黄星宇&#xff0c;审校为邱雪和许东舟。 一、会议介绍 ICPR…...

【深度学习】深刻理解BERT

BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是由Google于2018年提出的一种预训练的语言表示模型&#xff0c;它基于Transformer架构并能够处理自然语言处理&#xff08;NLP&#xff09;中的多种任务。BERT的核心创新是其使用了双向编…...

一种基于通义千问prompt辅助+Qwen2.5-coder-32b+Bolt.new+v0+Cursor的无代码对话网站构建方法

前言 今年似乎大模型之间的“内卷”已经有些偃旗息鼓了&#xff0c;各大技术公司逐渐从单纯追求模型参数量的竞赛中抽身&#xff0c;转向更加注重模型的实际应用效果与效率&#xff0c;开始内卷起了LLM“载具” 不知道这个词是不是我第一个发明的哈&#xff0c;总之我更喜欢…...

Java版-图论-最小生成树-Kruskal算法

实现描述 为了造出一棵最小生成树&#xff0c;我们从最小边权的边开始&#xff0c;按边权从小到大依次加入&#xff0c;如果某次加边产生了环&#xff0c;就扔掉这条边&#xff0c;直到加入了 n-1 条边&#xff0c;即形成了一棵树。 实现代码 首选我们对所有的边&#xff0c…...

计算机网络知识总结

1.网络协议是什么&#xff1f; 在计算机网络要做到有条不紊地交换数据&#xff0c;就必须遵守一些约定好的规则&#xff0c;比如交换数据地格式&#xff0c;是否需要发送一个应答信息。这些规则被称为网络协议。 分层结构 应用层&#xff1a;为计算机用户提供服务表示层&…...

普通算法——欧拉筛

欧拉筛 思路&#xff1a; 对欧拉筛的实现&#xff0c;主要是依靠一个数组模拟的栈来实现&#xff0c;核心思路为用栈储存已经发现的素数 在之后的遍历中&#xff0c;即可以素数数组中的数为因数来筛出此素数的倍数 遍历是以当前的 i i i 值为基数&#xff0c;来乘当前素数数…...

【知识科普】DNS(域名解析服务)深入解读

文章目录 概述一、基本概念二、域名解析的原理三、域名解析的类型四、域名解析的常见问题及解决方法五、域名解析的重要性 部署一、准备环境二、安装DNS软件三、配置DNS服务器四、测试DNS解析五、维护和管理DNS服务器 配置文件一、BIND DNS服务器配置文件格式二、Windows系统DN…...

数据结构第一弹-数据结构在不同领域的应用

大家好&#xff0c;今天和大家一起总结一下数据结构在不同领域和场景的应用~ 不同的数据结构适用于解决不同类型的问题&#xff0c;从简单的数组到复杂的图结构&#xff0c;每种数据结构都有其独特的应用场景。 1. 数组与链表 1.1 概念 数组&#xff1a;一种线性数据结构&a…...

如何创建基于udp的客户端和服务端

1.先创建好udpServer.hpp、udpServer.cc、udpClient.hpp、udpClient.cc的框架。 #pragma once #include <string> #include <iostream> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <cerrno> #include…...

ThinkPHP框架审计--基础

基础入门 搭建好thinkphp 查看版本方法&#xff0c;全局搜version 根据开发手册可以大致了解该框架的路由 例如访问url http://127.0.0.1:8094/index.php/index/index/index 对应代码位置 例如在代码下面添加新方法 那么访问这个方法的url就是 http://127.0.0.1:8094/index.…...

Java8 CompletableFuture异步编程

文章目录 CompletableFuturede介绍CompletableFuturede使用场景常用异步编程实现方案- Thread- ExecutorService- CountDownLatch- CyclicBarrier- ForkJoinPool- CompletableFuture各种实现方案总结 CompletableFuturede结构结构梳理- Future接口- CompletionStage接口常用方法…...

Java的Mvc整合Swagger的knife4框架

Swagger的介绍 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。使用Swagger&#xff0c;就是把相关的信息存储在它定义的描述文件里面&#xff08;yml或json格式&#xff09;&#xff0c;再通过维护这个描述 文件可以去更…...

分阶段构建在复杂系统中的应用:以推荐系统为例

引言 在信息技术飞速发展的今天&#xff0c;复杂系统的构建已经成为许多企业和组织面临的重要挑战。复杂系统通常由多个相互依赖、相互作用的组件构成&#xff0c;这些组件在功能上相互关联&#xff0c;形成了一个高度耦合的整体。对于这样的系统&#xff0c;采用分阶段构建的…...

2024年12月9日历史上的今天大事件早读

1447年12月9日 中国明朝皇帝明宪宗出生 1824年12月9日 西属美洲独立战争的阿亚库乔之战爆发 1882年12月9日 中国清代数学家李善兰逝世 1917年12月9日 葡萄牙共和政府垮台 1935年12月9日 红军表示与东北抗联军一致抗日 1935年12月9日 “一二九”运动爆发 1941年12月9日 中…...

快捷构建AI大模型,源码自取可直接运行

Node.js 和 WebSocket 实现一个基于kimi&#xff08;Moonshot 月之暗大模型&#xff09;的AI工具 前端&#xff1a;前端界面比较容易&#xff0c;只需要简单的额css js即可&#xff0c;本文使用vue作为作为demo。 后端&#xff1a;我java很垃圾&#xff0c;写不出好的代码&am…...

怎么为开源项目做贡献提PR?

GitHub 慢的话&#xff0c;https://ask.csdn.net/questions/8166374 复刻项目 以 https://github.com/open-frame/uniapp-init 项目为例 复刻完就会在你的仓库里有个同样的项目 拉取复刻下来的项目 然后常规的改动项目、git推送。比如我改了一个忽略文件&#xff1a; 提交…...

如何在 JavaScript 中设置定时器?

在 JavaScript 中&#xff0c;设置定时器通常使用两个内置的函数&#xff1a;setTimeout() 和 setInterval()。它们允许你在指定的时间延迟后执行某个函数或者以某个间隔反复执行某个函数。下面&#xff0c;我将结合实际项目代码示例讲解如何使用它们。 1. setTimeout() — 延…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么&#xff1f;1.1.2 感知机的工作原理 1.2 感知机的简单应用&#xff1a;基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill

视觉语言模型&#xff08;Vision-Language Models, VLMs&#xff09;&#xff0c;为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展&#xff0c;机器人仍难以胜任复杂的长时程任务&#xff08;如家具装配&#xff09;&#xff0c;主要受限于人…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

GO协程(Goroutine)问题总结

在使用Go语言来编写代码时&#xff0c;遇到的一些问题总结一下 [参考文档]&#xff1a;https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现&#xff1a; 今天在看到这个教程的时候&#xff0c;在自己的电…...