SpringBoot中注册Bean的方式汇总

文章目录

  • @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 {@Beanpublic ForlanBean forlanBean1(){return new ForlanBean();}
}@Component
// @Controller
// @Service
// @Repository
public class ForlanComponent {@Beanpublic 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 {@Overridepublic 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 {@Overridepublic 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.mzph.cn/news/814977.shtml

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

相关文章

大语言模型总结整理(不定期更新)

《【快捷部署】016_Ollama&#xff08;CPU only版&#xff09;》 介绍了如何一键快捷部署Ollama&#xff0c;今天就来看一下受欢迎的模型。 模型简介gemmaGemma是由谷歌及其DeepMind团队开发的一个新的开放模型。参数&#xff1a;2B&#xff08;1.6GB&#xff09;、7B&#xff…

文心一言 VS 讯飞星火 VS chatgpt (236)-- 算法导论17.3 2题

二、使用势能法重做练习17.1-3。练习17.1-3的内容是&#xff1a;假定我们对一个数据结构执行一个由 n 个操作组成的操作序列&#xff0c;当 i 严格为 2 的幂时第 i 个操作的代价为 i &#xff0c;否则代价为1。使用聚合分析确定每个操作的摊还代价。如果要写代码&#xff0c;请…

JAVA实现人工智能,采用框架SpringAI

Spring AI介绍 Spring AI是AI工程师的一个应用框架&#xff0c;它提供了一个友好的API和开发AI应用的抽象&#xff0c;旨在简化AI应用的开发工序&#xff0c;例如开发一款基于ChatGPT的对话应用程序。 项目地址&#xff1a;https://github.com/spring-projects-experimental/sp…

AGV小车导航避障雷达SE-0533(CNS-LS05C)激光传感器RS232|RS485|CAN BUS连线说明

AGV小车导航避障雷达SE-0533(CNS-LS05C)激光传感器广泛应用到AGV小车&#xff0c;RGV小车&#xff0c;无人叉车、搬运机器人等领域。本文重点介绍AGV小车导航避障雷达SE-0533(CNS-LS05C)激光传感器RS232|RS485|CAN BUS连线说明。 一、线序定义 1、传感器线缆线序定义 SE-053…

C++引用和右值引用

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

postgis导入shp数据时“dbf file (.dbf) can not be opened.“

作者进行矢量数据导入数据库中出现上述报错 导致报错原因 导入的shp文件路径太深导入的shp文件名称或路径中有中文将需要导入数据的shp 文件、dbf 文件、prj 等文件放在到同一个文件夹内&#xff0c;且名字要一致&#xff1b;导入失败&#xff1a; 导入成功&#xff1a;

js基础知识+练习

一&#xff0c;JavaScript简单了解 1.什么是JavaScript JavaScript简称JS&#xff0c;是较为流行的一种前端编程语言&#xff0c;是一种脚本语言&#xff0c;通过解释器运行&#xff0c;主要在客户端&#xff08;浏览器&#xff09;上运行&#xff0c;现在也可以基于node.js在服…

Python实现外观模式、桥接模式、组合模式和享元模式

今天介绍四种结构型设计模式&#xff1a;外观模式、桥接模式、组合模式和享元模式 外观模式 外观模式&#xff08;Facade Pattern&#xff09;&#xff0c;它为子系统提供一个统一的接口&#xff0c;使得子系统更加容易使用。 在Python中&#xff0c;我们可以通过定义一个外…

MYSQL08_页的概述、内部结构、文件头、文件尾、最大最小记录、页目录、区段表

文章目录 ①. 页的概述、大小②. 页的内部结构③. 第一部分 - 文件头④. 第一部分 - 文件尾⑤. 第二部分 - 空闲、用户记录、最大最小⑥. 第三部分 - 页目录⑦. 第三部分 - 页面头部⑧. 从数据页角度看B树⑨. 区、段和表、碎片区 ①. 页的概述、大小 ①. 数据库的存储结构&…

YOLO系列汇总 | 持续更新

文章目录 1 YOLOv1(2015, Joseph Redmon)2 YOLOv2(2016, Joseph Redmon)3 YOLOv3(2018, Joseph Redmon)4 YOLOv4(2020, Alexey Bochkovskiy, Chien-Yao Wang)5 YOLOV5(2021&#xff0c;Ultralytics)6 YOLOX(2021, Megvii旷视)7 YOLOv6(2022&#xff0c;美团)8 YOLOv7(2022&…

【深度学习】多层感知机与卷积神经网络解析

引言&#xff1a; 在人工智能的宏伟画卷中&#xff0c;深度学习如同一笔瑰丽而深邃的色彩&#xff0c;为这幅画增添了无限的生命力和潜能。作为支撑这一领域核心技术的基石&#xff0c;多层感知机&#xff08;MLP&#xff09;和卷积神经网络&#xff08;CNN&#xff09;在模仿人…

vivado ila 运行触发器、停止触发器、使用自动重新触发

运行触发器 您可在 2 种不同模式下运行或装备 ILA 核触发器 &#xff1a; • “ Run Trigger ” &#xff1a; 选择要装备的 ILA 核 &#xff0c; 然后单击“ ILA 仪表板 (ILA Dashboard) ”窗口或“硬件 (Hardware) ”窗口 工具栏上的“ Run Trigger ”按钮即可装备 IL…

MySQL :事务隔离级别实现方法

事务具有四个特性 原子性&#xff0c;要么全成功要么全失败&#xff0c;通过undo log实现持久性&#xff0c;不会因为断电等特殊情况造成数据丢失&#xff0c;通过redo log实现隔离性&#xff0c;事务之间互相不干扰&#xff0c;通过MVCC实现一致性&#xff0c;事务执行前后整…

Java中volatile关键字

保证了不同线程对这个变量进行操作时的可见性&#xff0c;即一个线程修改了某个变量的值&#xff0c;这新值对其他线程来说是立即可见的,volatile关键字会强制将修改的值立即写入主存。 1.volatile的可见性 一个典型的例子&#xff1a;永不停止的循环。 public class Forever…

【python】Python上海二手房数据分析可视化(数据集+源码+报告)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Electron 桌面端应用的使用 ---前端开发

Electron是什么&#xff1f; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许您保持一个 JavaScript 代码代码库并创建 在Windows上运行的跨平台应用 macOS和Linux——不需要本地开发 经验。 入门…

Spring Boot - 利用MDC(Mapped Diagnostic Context)实现轻量级同步/异步日志追踪

文章目录 Pre什么是MDC&#xff08;Mapped Diagnostic Context&#xff09;Slf4j 和 MDC基础工程工程结构POMlogback-spring.xmlapplication.yml同步方式方式一&#xff1a; 拦截器自定义日志拦截器添加拦截器 方式二&#xff1a; 自定义注解 AOP自定义注解 TraceLog切面 测试…

ES查询和监控

es安装 参考https://blog.csdn.net/okiwilldoit/article/details/137107087 再安装kibana&#xff0c;在它的控制台里写es查询语句。 es指南 es权威指南-中文版&#xff1a; kibana用户手册-中文版&#xff1a; es中文社区 es参考手册API es客户端API es查询语句 # 查询e…

Spring Boot:Web开发之三大组件的整合

Spring Boot 前言Spring Boot 整合 ServletSpring Boot 整合 FilterSpring Boot 整合 Listener前言 在 Web 开发中,Servlet 、Filter 和 Listener 是 Java Web 应用中的三大组件。Servlet 是 Java 代码,通过 Java 的 API 动态的向客户端输出内容。Filter 是处于客户端与服务…

74HC595引脚图时序图工作原理

74HC595和74hc164一样是在单片机系统中常用的芯片之一他的作用就是把串行的信号转为并行的信号&#xff0c;常用在各种数码管以及点阵屏的驱动芯片&#xff0c; 使用74HC595可以节约单片机mcu的io口资源&#xff0c;用3个io就可以控制8个数码管的引脚&#xff0c;他还具有一定的…