SpringBoot中注册Bean的方式汇总

news2024/11/27 22:45:02

文章目录

  • @ComponentScan + @Componet相关注解
  • @Bean
  • @Import
  • spring.factories
  • 总结
    • @Configuration和@Component的主要区别?
    • @Bean是不是必须和@Configuration一起使用?
    • @Import导入配置类有意义?
    • 出现异常:java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanDefinitionStoreException

@ComponentScan + @Componet相关注解

@Componet相关注解有@Configuration、@Controller、@Service、@Repository,配合@ComponentScan就能被扫描注册到Spring容器中。

定义我们需要注册的类

@Configuration
public class ForlanConfig {

	@Bean
	public ForlanBean forlanBean1(){
		return new ForlanBean();
	}
}

@Component
// @Controller
// @Service
// @Repository
public class ForlanComponent {

	@Bean
	public ForlanBean forlanBean2(){
		return new ForlanBean();
	}
}

public class ForlanBean {
}

验证如下:

public static void main(String[] args) {
	ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
	System.out.println(applicationContext.getBean("forlanConfig"));
	System.out.println(applicationContext.getBean("forlanComponent"));
}

// 输出如下:
cn.forlan.ForlanConfig$$EnhancerBySpringCGLIB$$e43dabb2@1305c126
cn.forlan.ForlanComponent@43af351a

@Bean

前面已经定义好需要注册的类,直接验证即可

验证如下:

public static void main(String[] args) {
	ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
	System.out.println(applicationContext.getBean("forlanBean1"));
	System.out.println(applicationContext.getBean("forlanBean2"));
}

// 输出如下:
cn.forlan.ForlanBean@64279ab
cn.forlan.ForlanBean@6650a6c

@Import

它可以导入的类有:Component, Configuration, ImportSelector, ImportBeanDefinitionRegistrar, ImportResource

定义我们需要注册的类

public class CaffeineForlanCache {
}

public class RedisForlanCache {
}

public class ForlanCustomize {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

实现ImportSelector

public class ForlanImportSelector implements ImportSelector {
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableForlanCache.class.getName());
		//通过 不同type注入不同的缓存到容器中
		CacheType cacheType = (CacheType) annotationAttributes.get("cacheType");
		if(cacheType.equals(CacheType.CAFFEINE)){
			return new String[]{CaffeineForlanCache.class.getName()};
		}else{
			return new String[]{RedisForlanCache.class.getName()};
		}
	}
} 

实现ImportBeanDefinitionRegistrar

public class ForlanBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(ForlanCustomize.class)
				.addPropertyValue("name", "forlan").getBeanDefinition();
		registry.registerBeanDefinition("forlanCustomize", beanDefinition);
	}
} 

定义注解导入

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ForlanImportSelector.class, ForlanBeanDefinitionRegistrar.class})
public @interface EnableForlanCache {
	CacheType cacheType() default CacheType.REDIS;
}

验证如下:

@EnableForlanCache(cacheType = CacheType.CAFFEINE)
public class Application {

	public static void main(String[] args) {
		ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
		System.out.println(applicationContext.getBean("forlanBean1"));
		System.out.println(applicationContext.getBean("forlanBean2"));
	}
}

// 输出如下:
cn.forlan.ForlanCustomize@245cb8df
cn.forlan.CaffeineForlanCache@578c3fd9
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.forlan.RedisForlanCache' available

spring.factories

定义我们需要注册的类

public class ForlanAutoConfiguration {
}

在resources\META-INF下新建spring.factories,填写内容,SpringBoot在启动时,就会自动注入

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.forlan.ForlanAutoConfiguration

验证如下:

public static void main(String[] args) {
	ConfigurableApplicationContext applicationContext = SpringApplication.run(Application.class, args);
	System.out.println(applicationContext.getBean(ForlanAutoConfiguration.class));
	System.out.println(applicationContext.getBean("cn.forlan.ForlanAutoConfiguration"));
}

// 输出如下:
cn.forlan.ForlanAutoConfiguration@19d53ab4
cn.forlan.ForlanAutoConfiguration@19d53ab4

注:这种方式的注入的BeanName为路径+类名

总结

总的来说,一共有如下几种方式可以注册bean:

  • @ComponentScan + @Componet相关注解
  • 使用@Bean注解
  • 使用@Import注解
  • spring.factories

@Configuration和@Component的主要区别?

使用场景:@Configuration主要用于定义配置类,其中包含了Bean的定义和配置;而@Component适用于任何需要被Spring管理的类。
功能:@Configuration主要用于配置类的定义和初始化Bean;而@Component主要用于组件的自动扫描和注册。

@Bean是不是必须和@Configuration一起使用?

不是的,尽管@Bean注解常常出现在带有@Configuration注解的配置类中,用于定义和初始化Spring容器中的Bean,但它也可以单独使用。@Bean注解的主要作用是告诉Spring框架,被该注解标注的方法将返回一个对象,这个对象需要被注册到Spring容器中。在非配置类中使用@Bean注解,只需要确保该方法能够被Spring扫描到即可。

@Import导入配置类有意义?

总结来说,@Import导入的类本身不是Bean,而是用于扩展Spring容器配置的工具。它可以定义或注册其他的Bean,但你不能直接通过applicationContext.getBean()获取这些导入类的实例。相反,你应该获取它们定义或注册的Bean的实例。它的主要价值在于动态注入Bean。

出现异常:java.lang.NoClassDefFoundError: Could not initialize class org.springframework.beans.factory.BeanDefinitionStoreException

原因是这个类写的有问题,ForlanImportSelector根本就没有初始化,不是是当前类
在这里插入图片描述

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

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

相关文章

巨控GRM230远程智能模块:定义未来智慧水务的新篇章

标签:#智能模块 #自动化控制 #远程监控 #水质检测 #无线数据传输 在如今这个快速发展的时代&#xff0c;智能化已经成为了各行各业升级转型的关键词。尤其在水务管理领域&#xff0c;传统的手动操作和监控方法逐渐不能满足现代化的需求&#xff0c;而巨控科技推出的GRM230远程…

Docker容器嵌入式开发:MySQL表的外键约束及其解决方法

本文内容涵盖了使用MySQL创建数据库和表、添加数据、处理字符集错误、解决外键约束问题以及使用SQL查询数据的过程。通过创建表、插入数据和调整字符集等操作&#xff0c;成功解决了数据库表中的字符集问题&#xff0c;并使用INSERT语句向各个表中添加了示例数据。同时&#xf…

12.C++常用的算法_遍历算法

文章目录 遍历算法1. for_each()代码工程运行结果 2. transform()代码工程运行结果 3. find()代码工程运行结果 遍历算法 1. for_each() 有两种方式&#xff1a; 1.普通函数 2.仿函数 代码工程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<vect…

【三十九】【算法分析与设计】综合练习(5),79. 单词搜索,1219. 黄金矿工,980. 不同路径 III

79. 单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相邻”单元格是那些水平…

二豆写作能用吗 #笔记#笔记

二豆写作是一款非常好用、靠谱、方便的论文写作工具&#xff0c;它能帮助用户快速完成论文写作&#xff0c;并且具有查重降重的功能。那么&#xff0c;二豆写作到底能不能用呢&#xff1f;答案是肯定的&#xff0c;二豆写作绝对是值得推荐的。 首先&#xff0c;二豆写作提供了丰…

不定长顺序表

一.不定长顺序表的结构: typedef struct DSQList{ int* elem;//动态内存的地址 int length;//有效数据的个数 int listsize;//总容量 }DSQList,*DPSQList; 很明显,为了能实现扩容(否则如何实现再次判满呢?),我们必须要在定长顺序表的基础上增加一个总容量;结构示意图如下: 二…

基于ros的相机内参标定过程

基于ros的相机内参标定过程 1. 安装还对应相机的驱动2. 启动相机节点发布主题3. 下载camera_calibartion4. 将红框的文件夹复制在自己的工作空间里边&#xff0c;编译5. 标定完成以后&#xff0c;生成内参参数文件camera.yaml。将文件放在对应的路径下&#xff0c;修改config文…

(二)ffmpeg 拉流推流示例

一、搭建流媒体服务器 在这里&#xff0c;选用的流媒体服务器是mediamtx。 下载地址&#xff1a;https://github.com/bluenviron/mediamtx/releases/tag/v1.6.0 系统不同选择的压缩包不同&#xff0c;我用的是ubuntu系统。 下载下来之后进行解压&#xff0c;可以看到里面有三…

【随笔】Git 高级篇 -- 最近标签距离查询 git describe(二十一)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

Android 属性动画及自定义3D旋转动画

Android 动画框架 其中包括&#xff0c;帧动画、视图动画&#xff08;补间动画&#xff09;、属性动画。 在Android3.0之前&#xff0c;视图动画一家独大&#xff0c;之后属性动画框架被推出。属性动画框架&#xff0c;基本可以实现所有的视图动画效果。 视图动画的效率较高…

常见性能测试工具对比

在性能测试工作中&#xff0c;我们常常会遇到好几个工具&#xff0c;但是每一个工具都有自己的优势&#xff0c;一时间不知道怎么选择。 今天我们就将性能测试常用的工具进行对比&#xff0c;这样大家在选择工具的时候心里就有底啦&#xff01; 阿里云PTS 性能测试PTS&#xff…

25. 文档测试

作为下午题出现的几率很低&#xff1b; 主要议题&#xff1a; 1.软件文档分类 2.用户文档的内容 用户文档测试的作用&#xff1a; 3.用户文档测试需要注意的问题 4.用户文档测试的要点 5.用户手册测试 6.在线帮助测试

安卓的认证测试

1 CTS CTS 是 Android 兼容性测试套件&#xff0c;用于验证设备是否符合 Android 平台的兼容性标准。它包含一系列测试用例&#xff0c;涵盖了设备的各个方面&#xff0c;如硬件功能、软件功能、API 的正确实现等。通过 CTS 测试&#xff0c;设备厂商可以确保其设备符合 Andro…

工单管理系统设计方案,工单系统的流程

工单管理系统是一种用于管理和跟踪工作流程的软件系统。它可以帮助企业和组织更好地分配任务、优化工作流程、提高生产效率和客户满意度。下面是一个基本的工单管理系统设计方案&#xff1a;需求分析  在设计工单管理系统之前&#xff0c;需要进行需求分析&#xff0c;确定系…

C语言 | Leetcode C语言题解之第17题电话号码的字母组合

题目&#xff1a; 题解&#xff1a; char phoneMap[11][5] {"\0", "\0", "abc\0", "def\0", "ghi\0", "jkl\0", "mno\0", "pqrs\0", "tuv\0", "wxyz\0"};char* digits…

【论文解读】大模型事实性调查(下)

http://t.csdnimg.cn/4md5U 上期我们分享了《大模型事实性调查》论文解读的前半部分&#xff0c;这一期为大家带来后面的内容&#xff0c;欢迎阅读交流。 四、事实性分析 在前面的第3节中&#xff0c;论文提供了与评估事实性相关的定量统计数据。在本节中&#xff0c;论文将更…

841. 钥匙和房间

841. 钥匙和房间 原题链接&#xff1a;完成情况&#xff1a;解题思路&#xff1a;参考代码&#xff1a;_841钥匙和房间_dfs_841钥匙和房间_bfs 错误经验吸取 原题链接&#xff1a; 841. 钥匙和房间 https://leetcode.cn/problems/keys-and-rooms/description/ 完成情况&…

Vue.js组件精讲 基础:Vue.js组件的三个API:prop、event、slot

如果您已经对 Vue.js 组件的基础用法了如指掌&#xff0c;可以跳过本小节&#xff0c;不过当做复习稍读一下也无妨。 组件的构成 一个再复杂的组件&#xff0c;都是由三部分组成的&#xff1a;prop、event、slot&#xff0c;它们构成了 Vue.js 组件的 API。如果你开发的是一个…

clickhouse深入浅出

基础知识原理 极致压缩率 极速查询性能 列式数据库管理 &#xff0c;读请求多 大批次更新或无更新 读很多但用很少 大量的列 列的值小数值/短字符串 一致性要求低 DBMS&#xff1a;动态创建/修改/删除库 表 视图&#xff0c;动态查/增/修/删&#xff0c;用户粒度设库…

llama2.c与chinese-baby-llama2语言模型本地部署推理

文章目录 简介Github文档克隆源码英文模型编译运行中文模型&#xff08;280M&#xff09;main函数 简介 llama2.c是一个极简的Llama 2 LLM全栈工具&#xff0c;使用一个简单的 700 行 C 文件 ( run.c ) 对其进行推理。llama2.c涉及LLM微调、模型构建、推理端末部署&#xff08…