Spring实战拆书--SpringBean

SpringBean生命周期详解 SpringBean生命周期详解 一、简述: Spring是我们每天都在使用的框架,Bean是被Spring管理的Java对象,是Spring框架最重要的部分之一,那么让我们一起了解一下Spring中Bean的生命周期是怎样的吧 二、流程图 我们先从宏观的角度看一下Spring的生命周期: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20201028174058916.png?x-oss-process=image/watermark,t ype_ZmFuZ3poZW5 阅读详情

1.准备工作

请在github上下载源码结合文章阅读,效果更佳

在创建了SpringBoot项目后,我们首先需要开启组件扫描,如下代码所示。


 
@Configuration //扫描指定包目录 @ComponentScan(basePackages="com.wjc") public class BeanConfig { } 

声明一个测试Bean的接口,全文的主要内容都是通过此接口的实现类完成的

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。


 
package com.wjc.spring.bean; public interface Bird { void fly(); void feed(); void twitter(); void changeTwiter(); } 

2.自动装配

自动装配是最常见的Bean装配形式。

我们首先写一个Bird接口的实现类来展示自动装配,只需一个“@Component”注解即可完成。


 
package com.wjc.spring.bean.impl; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.wjc.spring.bean.Bird; //这是知更鸟 @Component public class Robin implements Bird { private String flyStr ="知更鸟起飞"; private String feedStr = "不想吃东西"; private String twiterStr = "啊啊啊"; @Override public void fly() { System.out.println(flyStr); } @Override public void feed() { System.out.println(feedStr); } @Override public void twitter() { System.out.println(twiterStr); } @Override public void changeTwiter() { } } 

在测试时,我们只需要使用“@Autowired”注解,就可以拿到对应的对象了

通过Junit可以测试装配是否完成

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。


 
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=BeanConfig.class) public class BeanTest { @Autowired private Bird bird; //测试1,查看是否自动装配了知更鸟 //此时bean.impl只有robin @Test public void BeanTest1() { assertNotNull(bird); } } 

3.处理自动装配的歧义性(@Qualifier)

试想如果我有2个Bird接口的实现类,spring在装配时是否会因为不知道具体需要哪个实现类而报错?

此时声明一个“Parrot”,也实现bird接口,运行test方法会如何?


 
package com.wjc.spring.bean.impl; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.wjc.spring.bean.Bird; //这是鹦鹉 @Component public class Parrot implements Bird { private String flyStr ="鹦鹉起飞"; private String feedStr = "啥都吃"; private String twiterStr = "说人话"; @Override public void fly() { System.out.println(flyStr); } @Override public void feed() { System.out.println(feedStr); } @Override public void twitter() { System.out.println(twiterStr); } @Override public void changeTwiter() { twiterStr = "你好你好"; } } 

运行结果如下:

 


 
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.wjc.spring.test.BeanTest': Unsatisfied dependency expressed through field 'bird'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.wjc.spring.bean.Bird' available: expected single matching bean but found 5: parrot,quail,robin,Cuckoo1,Cuckoo2 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) 

可以看到,由于Spring并不知道应该将哪一个实现类注入到bird中,报出了 “UnsatisfiedDependencyException”,我们可以通过注解“@Qualifier("parrot")”来解决此问题


 
//这是鹦鹉 @Component @Qualifier("parrot") public class Parrot implements Bird { 

在获取实现类时使用如下方式,即可获取到自己想要的对象实例了


 
@Autowired @Qualifier("parrot") private Bird parrot; //添加@Qualifier("parrot")来解决声明问题 @Test public void BeanTest3() { // 此时鹦鹉添加了@Primary parrot.fly(); assertNotNull(parrot); } 

4.Bean的作用域

已知Spring默认是单例模式,但在多线程高并发的情况下,单例模式其实未必是最佳选择,如果线程A将Bean赋了值,而此时线程B拿取了被A赋值的对象,并返回了对应的结果,此时是不是会出现B返回了预料之外的结果?

本文简单讨论一下原型模式下Bean的传递,和会发生的问题,具体的各自作用域请百度“spring作用域”

已知Spring作用域如下:singleton / prototype / request / session /global session

我们来看一下如下代码,一个原型模式的对象


 
package com.wjc.spring.bean.impl; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.wjc.spring.bean.Bird; //这是鹌鹑 //这个使用原型模式 @Component @Qualifier("Quail") @Scope("prototype") public class Quail implements Bird { private String flyStr ="鹌鹑起飞"; private String feedStr = "鹌鹑想吃啥就吃啥"; private String twiterStr = "鹌鹑不知道怎么叫"; @Override public void fly() { // TODO Auto-generated method stub System.out.println(flyStr); } @Override public void feed() { // TODO Auto-generated method stub System.out.println(feedStr); } @Override public void twitter() { // TODO Auto-generated method stub System.out.println(twiterStr); } public void changeTwiter() { twiterStr = "我大鹌鹑今天就是饿死。。。。"; } } 

看下在TEST时他的表现如何:


 
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=BeanConfig.class) public class BeanTest3 { @Autowired @Qualifier("Quail") private Bird bird; @Autowired @Qualifier("Quail") private Bird bird2; //测试原型模式与单例的区别 @Test public void BeanTest1() { bird.twitter(); bird.changeTwiter(); bird.twitter(); bird2.twitter(); bird2.changeTwiter(); bird2.twitter(); } } 

运行结果:


 
鹌鹑不知道怎么叫 我大鹌鹑今天就是饿死。。。。 鹌鹑不知道怎么叫 我大鹌鹑今天就是饿死。。。。 

spring确实将此Bean对象变成了原型模式。那么作用域是否就这么简单的完成了?

我们看一下如下代码


 
@Service public class BirdServiceImpl implements BirdService { @Autowired @Qualifier("Quail") private Bird bird; public void ScopTest() { bird.twitter(); bird.changeTwiter(); bird.twitter(); } } 

运行测试类:


 
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=BeanConfig.class) public class ServiceTest { @Autowired private BirdService birdService; @Autowired private BirdService birdService2; //测试在Service上添加和不添加@Qualifier("Quail")时调用的Bean的区别 @Test public void ServiceTest2() { birdService.ScopTest(); birdService2.ScopTest(); } } 

运行结果:


 
鹌鹑不知道怎么叫 我大鹌鹑今天就是饿死。。。。 我大鹌鹑今天就是饿死。。。。 我大鹌鹑今天就是饿死。。。。 

????????原型模式失效了????

为什么会发生这种情况?因为在此场景下,“BirdServiceImpl”是单例模式的,对Bean的操作不可避免的变成了单例的,如果添加如下代码结果就会完全不一样


 
@Service @Scope("prototype") public class BirdServiceImpl implements BirdService { @Autowired @Qualifier("Quail") private Bird bird; public void ScopTest() { bird.twitter(); bird.changeTwiter(); bird.twitter(); } } 

再次运行时:


 
鹌鹑不知道怎么叫 我大鹌鹑今天就是饿死。。。。 鹌鹑不知道怎么叫 我大鹌鹑今天就是饿死。。。。 

假设“ServiceTest”方法为Control层,“BirdServiceImpl”方法为Service层,“Quail”为Bean,在实际应用时,应该考虑Scop注解是否会可以成功生效。

如下为测试后的结果


 
//当Service上有@Scope("prototype"),Bean上有@Scope("prototype")时 返回不同对象 //当Service上有@Scope("prototype"),Bean上无@Scope("prototype")时 返回相同对象 //当Service上无@Scope("prototype"),Bean上有@Scope("prototype")时 返回相同对象 //当Service上无@Scope("prototype"),Bean上无@Scope("prototype")时 返回相同对象 

5.注入式声明Bean

在上述代码中,我都是通过硬编码的形式在输入一些内容的,那么能否通过读取配置文件的方式完成输出内容呢?(实际运用场景:获取数据库连接对象Session)

我们首先定义一个对象,可以看到我没有添加任何注解,因为此对象不需要在这里进行装配!


 
package com.wjc.spring.bean.impl; import com.wjc.spring.bean.Bird; //这是杜鹃 public class Cuckoo implements Bird { private String flyStr = "fly" ; private String feedStr = "feed"; private String twiterStr = "twiter"; public Cuckoo(String flyStr, String feedStr, String twiterStr) { super(); this.flyStr = flyStr; this.feedStr = feedStr; this.twiterStr = twiterStr; } @Override public void fly() { // TODO Auto-generated method stub System.out.println(flyStr); } @Override public void feed() { // TODO Auto-generated method stub System.out.println(feedStr); } @Override public void twitter() { // TODO Auto-generated method stub System.out.println(twiterStr); } @Override public void changeTwiter() { // TODO Auto-generated method stub twiterStr = "杜鹃"; } } 

如果想学习Java工程化、高性能及分布式、深入浅出。微服务、Spring,MyBatis,Netty源码分析的朋友可以加我的Java高级交流:854630135,群里有阿里大牛直播讲解技术,以及Java大型互联网技术的视频免费分享给大家。

我们将Config改造一下,由他来负责装配对象


 
package com.wjc.spring.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.core.env.Environment; import com.wjc.spring.bean.impl.Cuckoo; @Configuration //扫描指定包目录 @ComponentScan(basePackages="com.wjc") @PropertySource("classpath:Cuckoo.properties") public class BeanConfig { //开启组件扫描 //获取资源 @Autowired private Environment env; //通过配置文件装配Cuckoo @Bean(name="Cuckoo1") public Cuckoo getbird() { return new Cuckoo(env.getProperty("flyStr","fly"), env.getProperty("feedStr","feed"), env.getProperty("twiterStr","twiter")); //return new Cuckoo("fly","feed", "twiter"); } @Bean(name="Cuckoo2") public Cuckoo getbird2() { return new Cuckoo("fly","feed", "twiter"); } } 

可以看到我声明了2个"Cuckoo"对象实例,分别叫“Cuckoo1”,“Cuckoo2”

使用Test方法来执行一下


 
package com.wjc.spring.test; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.wjc.spring.bean.impl.Cuckoo; import com.wjc.spring.config.BeanConfig; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=BeanConfig.class) public class BeanTest4 { @Autowired @Qualifier("Cuckoo2") private Cuckoo Cuckoo; @Autowired @Qualifier("Cuckoo1") private Cuckoo Cuckoo1; //测试通过配置文件装配Bean @Test public void BeanTest1() { Cuckoo1.fly(); Cuckoo1.feed(); Cuckoo1.twitter(); Cuckoo.fly(); Cuckoo.feed(); Cuckoo.twitter(); } } 

执行结果


 
cuckoo fly cuckoo feed cuckoo twiter fly feed twiter 

可以看到成功的声明了对象。

欢迎工作一到八年的Java工程师朋友们加入Java高级交流:854630135

本群提供免费的学习指导 架构资料 以及免费的解答

不懂得问题都可以在本群提出来 之后还会有直播平台和讲师直接交流噢

十一、增强现实 那都是n年前的老版本了,新版本完全没有这个问题,我就是纠结这个问题,搭建若干环境,又是vmware虚拟机,又是msys2,又是anaconda,又是找机器,折腾了几天,结果通通不是。以一张实际卡片为锚点,通过笔记本的摄像头,在显示器上将一个计算机内的3d物体显示在卡片上,类似于电影上看到的那种全息投影技术;如果你是想在windows环境下开发linux运行程序,那么CygWin/gcc是你的不二之选。而如果你想开发的是windows运行程序,并且追求速度,那么二者相比而言,MinGW是更好的选择。 阅读详情

相关推荐

企业信息化系统的组成模块-核心业务系统

通过标准化的数据流形成完整的业务闭环,CRM生成的销售订单驱动ERP的生产和采购,ERP将生产计划传递给MES执行,MES报工数据返回ERP进行成本核算,ERP再将交付信息同步给CRM供客户查询。生产管理确保高效交付,缩短订单周期。某贸易公司实施ERP供应链模块后,库存周转率从每年4次提升到8次,库存资金占用从2000万降到1200万,释放800万现金流,同时缺货率从15%降到5%。│ │库存 │ │ MRP │ │ ERP │ │ 云ERP/ │ │。

weiyvyy的博客 697

Java No qualifying bean of type * available: expected single matching bean but found问题解决

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'java.lang.Object' available: expected single matching bean but found 161 1、同时使用了@Component注解和@AllArgsContructor注解,但是没有加上@NoArgsConstructor注解,导致启动报错。

旭东怪的博客 6507

Informer复现 -- 完整模型

有了数据和核心的ProbAttention,接下来就可以复现完整的Informer(图1)了。图1:Informer模型结构[1]如果对图1还不太熟悉的同学,可以参考图2。由图2可知,informer与Transformer之间的差异并不大。主要区别是ProbAttention和可能的encoder最后一层的conv(源代码中用来distil)。图2:参考Transformer画的Informer模型结构。

AI_daily的博客 3493

Injection expected single matching bean but found

错误:expected single matching bean but found  改为

nb_forever的博客 857

STM32以太网通信-STM32以太网外设(ETH)

通过 DMA 控制器进行介质访问控制 (MAC) STM32F4xx系列控制器内部集成了一个以太网外设,它实际上是一个通过DMA控制器进行介质访问控制(MAC),它的功能就是实现MAC 层的任务。 借助以太网外设,STM32F4xx 控制器可以通过ETH 外设按照IEEE 802.3-2002 标准发送和接收MAC 数据包。 ETH 内部自带专用的DMA 控制器用于MAC,ETH 支持两个工业标准接口介质独立接口(MII)和简化介质独立接口(RMII)用于与外部PHY 芯片连接。MII 和RMII 接口用于

暖暖_的_纠结的博客 2万+

如何构建智能聊天系统

聊天分为听、思考、读,简单的通过ASR、LLM、TTS三类模型的组合可以实现,最近openai推出支持多模态的GPT-4o模型,可以把三个模型真正融合成在一起。现在市面上的模型百花齐放,各有所长。要实现可落地的方案,需要结合业务,验证模型效果,同时也要考虑方案的可行性,有些模型在国内能用,有些在国内不能用。

xsgnzb的专栏 2110

mybatis-plus的service注入报错问题:expected single matching bean but found 2

一、问题代码结构 1、service接口 public interface IUserService extends IService<User> {} 2、service接口实现类 @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {} 3、entity类 public class User { @Tabl

小小白的博客 8629

VScode搭建Opencv(C++开发环境)

VScode配置Opencv一、准备软件二 、下载软件1、MinGw下载2、 Cmake下载3、Opencv下载三、编译1、cmake-gui2、make3、install四、 VScode配置1、launch.json2、c_cpp_properties.json3、tasks.json五、测试 用了半天事件,看了各种的博客终于配置成功了,在这里记录并分享一下,让更多的人少走弯路。 本次环境是Win 10. 一、准备软件 我们本次用到的3个软件,(建议读者文件路径,文件版本 尽量都和我相同,这样不容易出错

河旬的博客 8万+

Spring中常见的bean创建异常

Spring中常见的bean创建异常1. 概述     本次我们将讨论在spring中BeanFactory创建bean实例时经常遇到的异常 org.springframework.beans.factory.BeanCreationException,下面我们将讨论并再现这些异常,同时给出解决方案。

Zone 12万+

冷源法测试噪声系数(Noise Figure)详细步骤

背景知识 电阻负载的功率谱密度 噪声等效模型 3 4 冷源法测试步骤 注意事项

eleday的电子世界 6873

如何通过conda安装HyPhy教程

本文介绍了在Ubuntu系统上通过conda安装分子进化分析工具HyPhy的详细步骤。首先创建conda环境并指定Python 3.8版本,然后通过bioconda通道安装HyPhy软件包。安装完成后可通过conda list命令验证安装。文中还特别指出可能遇到的libcrypto.so.1.1共享库缺失错误,并提供了解决方案的参考链接。该教程配有安装过程截图,帮助用户直观了解操作流程和验证安装结果。

猿小白的博客 8261

SpringBoot第三方jar包依赖 mvn打包错误解决方案(2个步骤)

原文解决方案:https://www.cnblogs.com/xiaosiyuan/p/6894766.html目录结构步骤一 pom里面将第三方的jar引入到maven里面来 (配合目录结构)&lt;!--添加外部依赖 start--&gt; &lt;dependency&gt; &lt;groupId&gt;wallet.alipay&lt;/groupId&gt...

屎壳郎情调-成长日记 2105

【11】GD32H7xx MPU记录

GD32H7xx系列MPU内存保护单元模块的使用记录

madao1234的博客 880

Spring——SpringBean初始接口

本文详细介绍了Spring框架中SpringBean的初始化接口和注解,包括BeanPostProcessor接口、InitializingBean接口和@PostConstruct注解。文章解释了这些接口和注解的原理、作用、适用场景,并提供了示例代码。最后,对比了不同SpringBean初始化方式的优缺点。

庄小焱 1404

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

springBean生命周期

一、springBean的生命周期 1、 启动spring容器,也就是创建beanFactory(bean工厂), 一般用的是beanFactory的子类applicationcontext, applicationcontext比一般的beanFactory要多很多功能,比如aop、事件等。 通过applicationcontext加载配置文件,或者利用注解的方式扫描将bean 的配置信息加载到spring容器里面。 2、 加载之后,spring容器会将这些

zhangCheng的博客 2万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SpringBean管理

在Spring中将管理对象称为 Bean.Bean是由一个SpringIOC容器实例化,组装和管理的对象.也就是说,Bean并不是由我们程序员编写的,而是在程序运行过程中,由Spring通过反射机制生成的.SpringBean是Spring框架在运行时管理的对象,我们编写的大多数逻辑代码都会存放在SpringBean中.

weixin_52629592的博客 2042

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

系统学习SpringFramework:SpringBean的注入方式

本篇内容包括:Spring 容器简介(什么是容器、容器如何工作)、SpringBean 注入方式(SpringBean 注入方式分类、@Autowiring 自动绑定)以及 获取 Spring Bean 的工具类!

栗筝i的博客 4829

Spring框架(SpringBean的作用域)

8 Bean的作用域 在 Spring 中, 可以在 元素的 scope 属性里设置 Bean 的作用域. 默认情况下, Spring 只为每个在 IOC 容器里声明的 Bean 创建唯一一个实例, 整个 IOC 容器范围内都能共享该实例:所有后续的 getBean() 调用和 Bean 引用都将返回这个唯一的 Bean 实例.该作用域被称为 singleton, 它是所有 Bean 的默认作用域.       Spring的作用域共有4种,根据使用情况而决定具体的选择    ...

qq_41649001的博客 702

SpringBean的常见面试题

什么是springbean? 由springioc容器管理的对象就是一个bean,是由ioc容器实例化,组装,管理的对象 javabean和springbean的区别? 所谓javaBean, 是指符合如下标准的Java类: 1.类是公共的 2.有一个无参的公共的构造器 3.有属性且有对应的get. set方法 配置bean有哪几种方式? 1.xml: <bean class=“com.tuling.UserService” id=> 2.注解: @Component(@Controller 、

qq_35757264的博客 1977

SpringBean

定义: Spring Bean是由Spring IoC容器管理的对象。是应用程序的核心组成部分,通常是服务、DAO、控制器等。XML配置: 通过XML文件定义Bean。</bean></beans>注解配置: 使用@Component@Service等注解定义Bean。@Component@ServiceJava配置: 使用和@Bean注解@Bean@Bean。

ny_forever的博客 1109

基于xml的Spring应用之SpringBean的配置详解

基于xml的Spring应用之SpringBean的配置详解

weixin_42594143的博客 1544

Springboot使用websocket注入SpringBean

开始:在webSocket中是不能直接使用autowired注入SpringBean的。 解决方法: 1.在webSocket类中加入以下代码。 /** * 解决无法注入 */ private static ApplicationContext applicationContext; //你要注入的bean private StudentRepo...

QuedYin的博客 1144

SpringBean学习总结

SpringBean 概述 BeanDefinition:主要用来描述Bean的定义 BeanDefinitionRegistry:提供了向IOC容器手动注册BeanDefinition的方法 BeanFactory:Spring框架最核心的接口 提供IOC的配置机制 包含Bean的各种定义,便于实例化Bean 建立Bean之间的依赖关系 Bean生命周期的控制 BeanFactory与Ap...

weixin_41021172的博客 574

Spring工具类 可以在非SpringBean 中调用SpringBean的方法

import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.BooleanUtils; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.s

weixin_43939924的博客 900
上一篇: 选择恐惧症的福音!教你认清MVC,MVP和MVVM
下一篇: Redis Cluster搭建高可用Redis服务器集群
javaQQ群 866865133
博客等级 码龄8年 59粉丝 309原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值