Spring 中 Bean 注入与获取
Spring 中有哪些方式可以把 Bean 注入到 IOC 容器?
关于这个问题,我的回答入下:把 Bean 注入到 IOC 容器里面的方式有 7 种方式
1. 使用 xml 的方式来声明 Bean 的定义,Spring 容器在启动的时候会加载并解析这
个 xml,把 bean 装载到 IOC 容器中。
例如:
<bean id="" name="" class=""> <property name="" value="" /><property name="" ref="" /><constructor-arg name="" value="" />
</bean>
spring会将装配好的bean存储在map(beanName->bean对象)中。
xml中的id对应map中的beanName,必须是唯一的
xml中的name对应map中的bean对象的alias(别名),可以有多个,通过逗号隔开,也是唯一的。
可以通过beanName或者alias获取bean。
此处还可以通过bean类型获取bean,如果该类型的bean存在多个则会报错。
ApplicationContext context=new ClassPathXmlApplicationContext(“applicationContext.xml”);
Music music=(Music) context.getBean(Music.class);
可以不声明id和name,如果这样默认id是【全类名#0】,name(alias)默认是【全类名】,假设再声明一个同样的bean则默认ID是全类名#1,没有alias。
2.使用@CompontScan 注解来扫描声明了@Controller、@Service、
@Repository、@Component 注解的类。
- 使用@Configuration 注解声明配置类,并使用@Bean 注解实现 Bean 的定义,
这种方式其实是 xml 配置方式的一种演变,是 Spring 迈入到无配置化时代的里程
碑。
- 使用@Import 注解,导入配置类或者普通的 Bean。
//类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;@Conditional({WindowsCondition.class})@Configuration@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})//@Import导入组件,id默认是组件的全类名public class MainConfig2 {//默认是单实例的/*** ConfigurableBeanFactory#SCOPE_PROTOTYPE * @see ConfigurableBeanFactory#SCOPE_SINGLETON * @see org.springframework.web.context.WebApplicationContext#SCOPE_REQUEST request* @see org.springframework.web.context.WebApplicationContext#SCOPE_SESSION sesssion* @return\* @Scope:调整作用域* prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。* 每次获取的时候才会调用方法创建对象;* singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。* 以后每次获取就是直接从容器(map.get())中拿,* request:同一次请求创建一个实例* session:同一个session创建一个实例* * 懒加载:* 单实例bean:默认在容器启动的时候创建对象;* 懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;* */// @Scope("prototype")@Lazy@Bean("person")public Person person(){System.out.println("给容器中添加Person....");return new Person("张三", 25);}/*** @Conditional({Condition}) : 按照一定的条件进行判断,满足条件给容器中注册bean* * 如果系统是windows,给容器中注册("bill")* 如果是linux系统,给容器中注册("linus")*/@Bean("bill")public Person person01(){return new Person("Bill Gates",62);}@Conditional(LinuxCondition.class)@Bean("linus")public Person person02(){return new Person("linus", 48);}/*** 给容器中注册组件;* 1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]* 2)、@Bean[导入的第三方包里面的组件]* 3)、@Import[快速给容器中导入一个组件]* 1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名* 2)、ImportSelector:返回需要导入的组件的全类名数组;* 3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中* 4)、使用Spring提供的 FactoryBean(工厂Bean);* 1)、默认获取到的是工厂bean调用getObject创建的对象* 2)、要获取工厂Bean本身,我们需要给id前面加一个&* &colorFactoryBean*/@Beanpublic ColorFactoryBean colorFactoryBean(){return new ColorFactoryBean();}
- 使用 FactoryBean 工厂 bean,动态构建一个 Bean 实例,Spring Cloud
OpenFeign 里面的动态代理实例就是使用 FactoryBean 来实现的。
/ /创建一个Spring定义的FactoryBeanpublic class ColorFactoryBean implements FactoryBean<Color> {//返回一个Color对象,这个对象会添加到容器中@Overridepublic Color getObject() throws Exception {// TODO Auto-generated method stubSystem.out.println("ColorFactoryBean...getObject...");return new Color();}@Overridepublic Class<?> getObjectType() {// TODO Auto-generated method stubreturn Color.class;}//是单例?//true:这个bean是单实例,在容器中保存一份0 //false:多实例,每次获取都会创建一个新的bean;@Overridepublic boolean isSingleton() {// TODO Auto-generated method stubreturn false;}}
Springboot有大量的@ConditionXXXX注解
public class LinuxCondition implements Condition {/*** ConditionContext:判断条件能使用的上下文(环境)* AnnotatedTypeMetadata:注释信息*/public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {// TODO是否linux系统//1、能获取到ioc使用的beanfactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();//2、获取类加载器ClassLoader classLoader = context.getClassLoader();//3、获取当前环境信息Environment environment = context.getEnvironment();//4、获取到bean定义的注册类BeanDefinitionRegistry registry = context.getRegistry();String property = environment.getProperty("os.name");
//可以判断容器中的bean注册情况,也可以给容器中注册beanboolean definition = registry.containsBeanDefinition("person");if(property.contains("linux")){return true;}return false;}}
- 实现 ImportBeanDefinitionRegistrar 接口,可以动态注入 Bean 实例。这个在
Spring Boot 里面的启动注解有用到。
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {/*** AnnotationMetadata:当前类的注解信息* BeanDefinitionRegistry:BeanDefinition注册类;* 把所有需要添加到容器中的bean;调用* BeanDefinitionRegistry.registerBeanDefinition手工注册进来*/@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {boolean definition = registry.containsBeanDefinition("com.atguigu.bean.Red");boolean definition2 = registry.containsBeanDefinition("com.atguigu.bean.Blue");if(definition && definition2){//指定Bean定义信息;(Bean的类型,Bean。。。)RootBeanDefinition beanDefinition = new RootBeanDefinition(RainBow.class);//注册一个Bean,指定bean名registry.registerBeanDefinition("rainBow", beanDefinition);}}}
- 实现 ImportSelector 接口,动态批量注入配置类或者 Bean 对象,这个在 SpringBoot 里面的自动装配机制里面有用到。
public class MyImportSelector implements ImportSelector {//返回值,就是到导入到容器中的组件全类名//AnnotationMetadata:当前标注@Import注解的类的所有注解信息public String[] selectImports(AnnotationMetadata importingClassMetadata) {// TODO Auto-generated method stub//importingClassMetadata//方法不要返回null值return new String[]{"com.atguigu.bean.Blue","com.atguigu.bean.Yellow"};}}
获取Spring中bean的5种方式
获取Spring中的bean有很多种方式,再次总结一下:
第一种:在初始化时保存ApplicationContext对象
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
说明:这种方式适用于采用Spring框架的独立应用程序,需要程序通过配置文件手工初始化Spring。
第二种:通过Spring提供的工具类获取ApplicationContext对象
import org.springframework.web.context.support.WebApplicationContextUtils;
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
ac2.getBean("beanId");
说明:
1、这两种方式适合于采用Spring框架的B/S系统,通过ServletContext对象获取ApplicationContext对象,然后在通过它获取需要的类实例;
2、第一种方式在获取失败时抛出异常,第二种方式返回null。
第三种:继承自抽象类ApplicationObjectSupport
说明:通过抽象类ApplicationObjectSupport提供的getApplicationContext()方法可以方便的获取到ApplicationContext实例,进而获取Spring容器中的bean。Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。
第四种:继承自抽象类WebApplicationObjectSupport
说明:和上面方法类似,通过调用getWebApplicationContext()获取WebApplicationContext实例;
第五种:实现接口ApplicationContextAware
说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext对象。Spring初始化时,会通过该方法将ApplicationContext对象注入。
虽然Spring提供了后三种方法可以实现在普通的类中继承或实现相应的类或接口来获取Spring的ApplicationContext对象,但是在使用时一定要注意继承或实现这些抽象类或接口的普通java类一定要在Spring的配置文件(即application-context.xml文件)中进行配置,否则获取的ApplicationContext对象将为null。
下面通过实现接口ApplicationContextAware的方式演示如何获取Spring容器中的bean:
首先自定义一个实现了ApplicationContextAware接口的类,实现里面的方法:
package com.ghj.tool;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;public class SpringConfigTool implements ApplicationContextAware {// extends ApplicationObjectSupport{private static ApplicationContext ac = null;private static SpringConfigTool springConfigTool = null;public synchronized static SpringConfigTool init() {if (springConfigTool == null) {springConfigTool = new SpringConfigTool();}return springConfigTool;}public void setApplicationContext(ApplicationContext applicationContext)throws BeansException {ac = applicationContext;}public synchronized static Object getBean(String beanName) {return ac.getBean(beanName);}
}
其次在applicationContext.xml文件进行配置:
<bean id="SpringConfigTool" class="com.ghj.tool.SpringConfigTool"/>
最后通过如下代码就可以获取到Spring容器中相应的bean了:
SpringConfigTool.getBean("beanId");
注意一点,在服务器启动Spring容器初始化时,不能通过以下方法获取Spring容器:
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext; WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
wac.getBean(beanID);
相关文章:
Spring 中 Bean 注入与获取
Spring 中有哪些方式可以把 Bean 注入到 IOC 容器? 关于这个问题,我的回答入下:把 Bean 注入到 IOC 容器里面的方式有 7 种方式 1. 使用 xml 的方式来声明 Bean 的定义,Spring 容器在启动的时候会加载并解析这 个 xml,…...
STM32 中断复习
中断 打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断。 在确定时间内对相应事件作出响应,如:温度监控(定时器中断)。故障处理,检测到故障&#x…...
Django的模型
定义模型 from django.db import models class User(models.Model):# 类属性是表示表的字段username models.CharField(max_length50,uniqueTrue)password models.CharField(max_length200)create_time models.DateTimeField(auto_now_addTrue) # auto_now_add新增数据时间…...
非计算机科班如何丝滑转码
近年来,很多人想要从其他行业跳槽转入计算机领域。非计算机科班如何丝滑转码? 方向一:如何规划才能实现转码? 对于非计算机科班的人来说,想要在计算机领域实现顺利的转码并不是一件容易的事情,但也并非不…...
PyTorch深度学习实战(12)——数据增强
PyTorch深度学习实战(12)——数据增强 0. 前言1. 图像增强1.1 仿射变换1.2 亮度修改1.3 添加噪音1.4 联合使用多个增强方法 2. 对批图像执行图像增强3. 利用数据增强训练模型小结系列链接 0. 前言 数据增强是指通过对原始数据进行一系列变换和处理&…...
SpringCloud Ribbon中的7种负载均衡策略
SpringCloud Ribbon中的7种负载均衡策略 Ribbon 介绍负载均衡设置7种负载均衡策略1.轮询策略2.权重策略3.随机策略4.最小连接数策略5.重试策略6.可用性敏感策略7.区域敏感策略 总结 负载均衡通器常有两种实现手段,一种是服务端负载均衡器,另一种是客户端…...
04 qt功能类、对话框类和文件操作
一 QT中时间和日期 时间 ---- QTime日期 ---- QDate对于Qt而言,在实际的开发过程中, 1)开发者可能知道所要使用的类 ---- >帮助手册 —>索引 -->直接输入类名进行查找 2)开发者可能不知道所要使用的类,只知道开发需求文档 ----> 帮助 手册,按下图操作: 1 …...
安装软件包
安装软件包 创建一个名为 /home/curtis/ansible/packages.yml 的 playbook : 将 php 和 mariadb 软件包安装到 dev、test 和 prod 主机组中的主机上 将 RPM Development Tools 软件包组安装到 dev 主机组中的主机上 将 dev 主机组中主机上的所有软件包更新为最新版本 vim packa…...
玩转单元测试之gmock
引言 前文我们学习了gtest相关的使用,单靠gtest,有些场景仍然无法进行测试,因此就诞生了gmock。 gmock快速入门 在引入gtest时,gmock也同样引入了,因此只需要在编译时加上合适的编译选项即可,注意不同版…...
POI与EasyExcel--写Excel
简单写入 03和07版的简单写入注意事项: 1. 对象不同:03对应HSSFWorkbook,07对应XSSFWorkbook 2. 文件后缀不同:03对应xls,07对应xlsx package com.zrf;import org.apache.poi.hssf.usermodel.HSSFWorkbook; import …...
7. CSS(四)
目录 一、浮动 (一)传统网页布局的三种方式 (二)标准流(普通流/文档流) (三)为什么需要浮动? (四)什么是浮动 (五)浮…...
uni-app 集成推送
研究了几天,终于是打通了uni-app的推送,本文主要针对的是App端的推送开发过程,分为在线推送和离线推送。我们使用uni-app官方推荐的uni-push2.0。官方文档 准备工作:开通uni-push功能 勾选uniPush2.0点击"配置"填写表单…...
Spring Boot+Redis 实现消息队列实践示例
Spring BootRedis 实现一个轻量级的消息队列 文章目录 Spring BootRedis 实现一个轻量级的消息队列0.前言1.基础介绍2.步骤2.1. 引入依赖2.2. 配置文件2.3. 核心源码 4.总结答疑 5.参考文档6. Redis从入门到精通系列文章 0.前言 本文将介绍如何利用Spring Boot与Redis结合实现…...
11. 实现业务功能--获取用户信息
目录 1. 实现 Controller 2. 单体测试 3. 修复返回值存在的缺陷 3.1 用户的隐私数据:密码的密文和盐不能显示 3.2 将值为 null 的字段可以进行过滤 3.3 时间的格式需要进行处理,如 yyyy-mmmm-ddd HH:mm:ss 3.4 data 属性没有返回 4. 实现前端页…...
HTTPS
HTTPS是什么 HTTPS 属于应用层协议,其原理是通过SSL/TLS协议在HTTP和TCP之间插入一层安全机制。通过SSL/TLS握手过程,客户端和服务器协商出一个对称密钥,用于后续的数据加密和解密,从而保证数据的机密性和完整性。 为什么会需要…...
spring详解
spring是于2003年兴起的一款轻量级的,非侵入式的IOC和AOP的一站式的java开发框架,为简化企业级应用开发而生。 轻量级的:指的是spring核心功能的jar包不大。 非侵入式的:业务代码不需要继承或实现spring中任何的类或接口 IOC&…...
香港服务器备案会通过吗?
对于企业或个人来说,合规备案是网络运营的基本要求,也是保护自身权益的重要举措。以下内容围绕备案展开话题,希望为您解开疑惑。 香港服务器备案会通过吗? 目前,香港服务器无法备案,这是由于国内管理规定的限制…...
乐鑫推出 ESP ZeroCode 控制台
乐鑫科技 ESP ZeroCode 控制台是一个网页应用,用户只需点击鼠标,描述想要创建的产品类型、功能及其硬件配置,即可按照自身需求,快速生成符合 Matter 认证的固件,并在硬件上进行试用。试用过程中,如有任何不…...
从NLP到聊天机器人
一、说明 今天,当打电话给银行或其他公司时,听到电话另一端的机器人向你打招呼是很常见的:“你好,我是你的数字助理。请问你的问题。是的,机器人现在不仅可以说人类语言,还可以用人类语言与用户互动。这是由…...
相关搜索引擎常用搜索语法(Google hacking语法和FOFA语法)
一:Google Hack语法 Google Hacking原指利用Google搜索引擎搜索信息来进行入侵的技术和行为,现指利用各种搜索引擎并使用一些高级的搜索语法来搜索信息。既利用搜索引擎强大的搜索功能,在在浩瀚的互联网中搜索到我们需要的信息。 ࿰…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
五年级数学知识边界总结思考-下册
目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解:由来、作用与意义**一、知识点核心内容****二、知识点的由来:从生活实践到数学抽象****三、知识的作用:解决实际问题的工具****四、学习的意义:培养核心素养…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信 BLE Mesh协议的拓扑结构 定向转发机制
目录 节点的功能承载层(GATT/Adv)局限性: 拓扑关系定向转发机制定向转发意义 CG 节点的功能 节点的功能由节点支持的特性和功能决定。所有节点都能够发送和接收网格消息。节点还可以选择支持一个或多个附加功能,如 Configuration …...
Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...
rknn toolkit2搭建和推理
安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
