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

Spring加载Bean的多种方式

文章目录

  • 1. XML方式定义
  • 2. 使用@Component + @ComponentScan
  • 3. 使用@Configuration + @Bean
  • 4. 使用FactoryBean的方式加载bean
  • 5. Import方式
  • 6. @Import + @ImportSelector
  • 7. @Import + ImportBeanDefinitionRegistrar
  • 8. 实现接口BeanDefinitionRegistryPostProcessor
  • 9. 实现接口BeanFactoryPostProcessor

Spring的IOC特性,使得其加载bean的方式有很多,这里记录一下加载bean的9种方式:

1. XML方式定义

这种方式在早起的项目中很常见,但是由于容易导致配置文件的爆炸式增长,致使其难以维护,现在的使用已经越来越少。

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="person" class="com.example.Person"/>
</beans>

在Java代码中可以获取名为person的bean。

class Person {
}public class Test {public static void main(String[] args) {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-config.xml");
System.out.println(applicationContext.getBean("person"));
}

这样我们可以轻松获取到bean。

2. 使用@Component + @ComponentScan

用@ComponentScan指定需要扫描的包,然后指定包下的标注了指定注解的类加载为bean。这里的注解包括但不限于:@Component,@Service, @Controller, @Repository。
这里要注意一点,springboot默认扫描启动类所在包以及其子包,所以很多时候我们看起来只是在类上加了注解就已经可以加载到Bean了。

3. 使用@Configuration + @Bean

有些Bean不是我们自己定义的,那么我们无法在这个类上添加注解,因此可以通过这个方法来加载Bean。

class Person {
}@Configuration
public class Config {@Beanpublic Person person() {return new Person();}
}

这样我们就可以从context中获取到名为person的Bean。当然,也可以在@Bean注解上指定Bean的name,即**@Bean(“customPerson”)**

4. 使用FactoryBean的方式加载bean

通过实现FactoryBean接口,来加载bean,这里其实是代理的方式在创建bean。

class Person {}@Component
public class PersonFactoryBean implements FactoryBean<Person> {@Overridepublic Person getObject() throws Exception {return new Person();}@Overridepublic Class<?> getObjectType() {return Person.class;}@Overridepublic boolean isSingleton() {return FactoryBean.super.isSingleton();}
}

实现了FactoryBean接口的类,它在spring容器中本身也是一个bean。这个bean的name与普通bean不同,将会以**&**开头,因此我们要获取这个类的时候,需要使用的bean名称是“&”+类名。这里就是“&PersonFactoryBean”。那么如何获取这个FactoryBean要产生的类呢?
我们已经获取了这个“FactoryBean”的bean,那么就可以通过其getObject()方法,获取这个person bean。
这样获取的话也是有些麻烦,所以我们可以直接获取名为“personFactoryBean”这个的这个bean,这个是由容器帮我们生成的,且这个bean就是Person类型的bean。

public static void main(String[] args) throws Exception {var context = new AnnotationConfigApplicationContext(SpringApplication.class);var bean = context.getBean("personFactoryBean");if (bean instanceof PersonFactoryBean) {System.out.println("personFactoryBean=====");} //这里的bean类型,是Person,并不是FactoryBeanvar bean1 = context.getBean("&personFactoryBean");//这个是FactoryBean本身的Beanif (bean1 instanceof PersonFactoryBean) {System.out.println(Objects.requireNonNull(((PersonFactoryBean) bean1).getObject()).getName());}Person person = (Person) context.getBean("personFactoryBean");System.out.println(person.getName());//直接获取这个person Bean}

5. Import方式

class Person {}@SpringBootApplicatioin
@Import({Person.class})
public class Application{public static void main(String[] args) {var context = new AnnotationConfigApplicationContext(Sj1123Application.class);Person person = (Person) context.getBean("com.example.sj1123.entity.Person");}}

这样就可以获取到Person类型的Bean。但是这里要注意的是,这个bean的名称,是类的全限定名,不是简单的person。

6. @Import + @ImportSelector

使用ImportSelector的好处:

  • 1、把某个功能的相关类放到一起,方面管理和维护。
  • 2、重写selectImports方法时,能够根据条件判断某些类是否需要被实例化,或者某个条件实例化这些bean,其他的条件实例化那些bean等,我们能够非常灵活的定制化bean的实例化。

这种方式我们需要实现ImportSelector接口,并重写selectImports()方法,然后将我们要导入的类的全限定名写在里面即可。

class Person {}class PersonImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"com.example.sj1123.entity.Person"};}
}@SpringBootApplicatioin
@Import({PersonImportSelector.class})
public class Application{public static void main(String[] args) {var context = new AnnotationConfigApplicationContext(Sj1123Application.class);Person person = (Person) context.getBean("com.example.sj1123.entity.Person");}}

这里获取bean时,bean的名称仍然是全限定名。

7. @Import + ImportBeanDefinitionRegistrar

这种方式需要实现ImportBeanDefinitionRegistrar接口,并重写registerBeanDefinitions()方法,然后定义需要注册的Bean的定义信息,然后registry.registerBeanDefinition()方法注册即可。这种方式比ImportSelector更加灵活,可以自定义bean的名称、作用域等很多参数。

class Person {}class PersonBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(@NonNull AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {ImportBeanDefinitionRegistrar.super.registerBeanDefinitions(importingClassMetadata, registry, importBeanNameGenerator);registry.registerBeanDefinition("person", new RootBeanDefinition(Person.class));}
}@SpringBootApplicatioin
@Import({PersonBeanDefinitionRegister.class})
public class Application{public static void main(String[] args) {var context = new AnnotationConfigApplicationContext(Sj1123Application.class);Person person = (Person) context.getBean("person");}}

8. 实现接口BeanDefinitionRegistryPostProcessor

在Spring容器启动方法refresh()方法的invokeBeanFactoryPostProcessors()方法中,会执行 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry()方法,它允许对beanDefinition进行后置处理,我们可以在这个方法调整IOC容器中的beanDefinition定义信息,从而干扰到后面bean初始化的过程。

class Person {}@Component
public class PersonBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {registry.registerBeanDefinition("person", new RootBeanDefinition(Person.class));}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}@SpringBootApplicatioin
public class Application{public static void main(String[] args) {var context = new AnnotationConfigApplicationContext(Sj1123Application.class);Person person = (Person) context.getBean("person");}}

9. 实现接口BeanFactoryPostProcessor

BeanDefinitionRegistryPostProcessor就是继承自BeanFactoryPostProcessor,所以使用BeanFactoryPostProcessor也可以实现注册Bean的功能。它们的区别如下:

  • 1、 BeanDefinitionRegistryPostProcessor:侧重于bean的注册;
  • 2、 BeanFactoryPostProcessor:侧重于对已经注册的bean的属性进行。
class Person {}@Component
public class PersonBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {((DefaultListableBeanFactory)beanFactory).registerBeanDefinition("person", new RootBeanDefinition(Person.class));}
}@SpringBootApplicatioin
public class Application{public static void main(String[] args) {var context = new AnnotationConfigApplicationContext(Sj1123Application.class);Person person = (Person) context.getBean("person");}}

相关文章:

Spring加载Bean的多种方式

文章目录 1. XML方式定义2. 使用Component ComponentScan3. 使用Configuration Bean4. 使用FactoryBean的方式加载bean5. Import方式6. Import ImportSelector7. Import ImportBeanDefinitionRegistrar8. 实现接口BeanDefinitionRegistryPostProcessor9. 实现接口BeanFacto…...

minio分布式存储系统

目录 拉取docker镜像 minio所需要的依赖 文件存放的位置 手动上传文件到minio中 工具类上传 yml配置 config类 service类 启动类 测试类 图片 视频 删除minio服务器的文件 下载minio服务器的文件 拉取docker镜像 拉取稳定版本:docker pull minio/minio:RELEASE.20…...

Kafka 如何保证消息消费的全局顺序性

哈喽大家好&#xff0c;我是咸鱼 今天我们继续来讲一讲 Kafka 当有消息被生产出来的时候&#xff0c;如果没有指定分区或者指定 key &#xff0c;那么消费会按照【轮询】的方式均匀地分配到所有可用分区中&#xff0c;但不一定按照分区顺序来分配 我们知道&#xff0c;在 Kaf…...

boa+cgi上传文件超过1M报错问题

写在前面 今天需要使用页面上传bin包&#xff0c;文件大概是3.9mb&#xff0c;结果一直报错 POST /cgi-bin/Upgrade.cgi undefined Host: 192.168.137.200:8888 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:120.0) Gecko/20100101 Firefox/120.0 Accept: text/h…...

抖去推--短视频账号矩阵系统saas工具源码技术开发(源头)

一、短视频矩阵系统搭建常见问题&#xff1f; 1、抖去推的短视频AI矩阵营销软件需要一定的技术水平吗&#xff1f; 答&#xff1a;不需要。产品简单易用&#xff0c;不需要具备专业的技术水平&#xff0c;即使是初学者&#xff0c;也能够轻松上手操作。 3、抖去推的短视频AI矩…...

【服务器能干什么】搭建一个短网址平台,可以查看数据详情!

昨天在 YouTube 上看到又一个搭建自己短网址的视频教程&#xff0c;用的是开源的 polr&#xff0c;但是按照步骤一步步搭建下来&#xff0c;最后一步都会出现 顺哥轻创 PLAINTEXT Whoops, looks like something went wrong百度、谷歌查了一圈也没找到有效的解决方法。&#x…...

MySQL备份与恢复(重点)

MySQL备份与恢复&#xff08;重点&#xff09; 一、用户管理与权限管理 ☆ 用户管理 1、创建MySQL用户 注意&#xff1a;MySQL中不能单纯通过用户名来说明用户&#xff0c;必须要加上主机。如jack10.1.1.1 基本语法&#xff1a; mysql> create user 用户名被允许连接的主…...

机器学习中的特征选择:方法和 Python 示例

布拉加德什桑达拉拉詹 一、说明 特征选择是机器学习流程中至关重要且经常被低估的步骤。它涉及从数据集中的原始特征集中选择最相关的特征&#xff08;输入变量或属性&#xff09;的子集。特征选择的重要性怎么强调都不为过&#xff0c;因为它直接影响机器学习模型的质量、效率…...

有哪些不错的golang开源项目?

前言 下面是github上的golang项目&#xff0c;适合练手&#xff0c;可以自己选择一些项目去练习&#xff0c;整理不易&#xff0c;希望能多多点赞收藏一下&#xff01;废话少说&#xff0c;我们直接进入正题>>> 先推荐几个教程性质的项目&#xff08;用于新手学习、…...

解决ssh使用public key远程登录服务器拒绝问题

目录 使用场景windows安装ssh客户端使用powershell ssh登录服务器生成密钥文件ubuntu ssh服务器配置使用vscode远程登录使用Xshell远程登录使用MobaXtem远程登录Server refused our key问题解决方案 使用场景 使用vscode远程ssh登录使用public key不需要输入密码,比较方便. w…...

js数组中,相同id的item数据合并

原数据&#xff1a; const list [ {id:1, key: a}, {id:1, key: b}, {id:2, key: c}, {id:2, key: d}, ]期望数据格式 const newList [ {id:1, keyList: [a,b]}, {id:2, keyList: [c,d]}, ]// 相同id的数据合并let newList_(list ).flatten().groupBy(id).map(_.spread((..…...

LeetCode(33)最小覆盖子串【滑动窗口】【困难】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 76. 最小覆盖子串 1.题目 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 "" 。 注意&#xff1a; 对于 t 中重复字…...

设计模式 创建者模式

设计模式 创建者模式 前言原来代码使用设计模式总结Builder模式在源码中的应用&#xff1a;其他代码 前言 “对象创建”模式——绕开new 工厂模式 抽象工厂 原型模式 构建器 动机与背景 目前需要建造一个房子&#xff0c;建造房子需要一系列特定的步骤&#xff0c;但是房子的类…...

排序算法--插入排序

实现逻辑 ① 从第一个元素开始&#xff0c;该元素可以认为已经被排序 ② 取出下一个元素&#xff0c;在已经排序的元素序列中从后向前扫描 ③如果该元素&#xff08;已排序&#xff09;大于新元素&#xff0c;将该元素移到下一位置 ④ 重复步骤③&#xff0c;直到找到已排序的元…...

【操作宝典】SQL巨擘:掌握SQL Server Management的终极秘籍!

目录 ⛳️【SQL Server Management】 ⛳️1. 启动登录 ⛳️2. 忘记密码 ⛳️3. 操作数据库和表 3.1 新建数据库text 3.2 新建表 3.3 编辑表 3.4 编写脚本 ⛳️【SQL Server Management】 ⛳️1. 启动登录 需要开启服务 ⛳️2. 忘记密码 登录windows--> 安全性 -->…...

Airtest遇到模拟器无法输入中文的情况该如何处理?

1. 前言 最近有收到同学们的一些提问&#xff0c;使用Airtest的 text 接口&#xff0c;发现在部分模拟器上&#xff0c; text 无法输入中文&#xff0c;不知道该怎么处理。 今天我们就输入这个小问题&#xff0c;来详细聊一下。 2. Airtest的输入法简介 对于Android设备来说…...

从农夫山泉家族任命,看“食企二代”的接班与传承

本文转载自产业科技 农夫山泉再次引发舆论关注&#xff0c;起因是一则人事任命消息。 市场消息称&#xff0c;农夫山泉对区域及人员进行了调整&#xff0c;其总部所在地浙江省被划分为四个区域&#xff0c;在以往浙南、浙北基础上多了浙西大区以及杭州大区&#xff0c;其中农…...

JavaScript启动本地应用程序

JavaScript调起本地应用程序 以下内容&#xff0c;自定义部分我也还未经过实际验证&#xff0c;酌情查看。 文章目录 JavaScript调起本地应用程序确定协议调用协议传参自定义写入协议获取参数 在浏览器中通过 JavaScript调起本地应用程序的一个可行方法就是 通过协议调起。 …...

软件工程理论与实践 (吕云翔)第十四章 软件维护与软件工程管理课后习题与解析

第十四章 软件维护与软件工程管理 1.判断题 &#xff08;1&#xff09;代码行技术是比较简单的定量估算软件规模的方法。(√) &#xff08;2&#xff09;功能点技术依据对软件信息域特性和软件复杂性的评估结果&#xff0c;估算软件规模。&#xff08;√&#xff09; &#…...

Flutter 桌面应用开发之读写Windows注册表

文章目录 需求来源Windows查询Windows版本号方法1. 如何查看Windows版本号2. Windows开发如何通过代码查询Windows版本号(1) 使用C#代码&#xff1a;(2) 使用VB.NET代码 3.通过注册表查看Windows版本信息 Flutter查询Windows版本号方法依赖库支持平台实现步骤1. 在pubspec.yaml…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动&#xff08;如演唱会、马拉松赛事、高考中考等&#xff09;期间&#xff0c;城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例&#xff0c;暖城商圈曾因观众集中离场导致周边…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...