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

SpringIoC组件的高级特性

目录

一、Bean组件的周期与作用域

二、FactoryBean接口


一、Bean组件的周期与作用域

1.1 Bean组件的生命周期

什么是Bean的周期方法

  1. 我们可以在组件类中定义方法,然后当IoC容器实例化和销毁组件对象的时候进行调用!这两个方法我们成为生命周期方法!
  2. 类似于Servlet的init/ service/destroy方法,我们可以在周期方法完成初始化和释放资源等工作。
  3. Bean只有两种周期,init与destory,即初始化和销毁。

1.2 Bean生命周期的代码实现
创建组件类:

package com.alphamilk.Ioc5;public class JavaBean {/*注意:使用周期方法时候,对应的方法必须满足以下几点1.无参2.返回值类型为void*/public void init(){System.out.println("javaBean被初始化");}public  void destory(){System.out.println("JavaBean被正常销毁");}
}

创建对应的配置文件xml

<?xml version="1.0" encoding="UTF-8"?>
<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"><!--    组件创建前面都是一样的,但是需要加上对应的周期方法:1.init-method 初始化组件方法 2.destroy-method 销毁组件方法
--><bean id="javaBean" class="com.alphamilk.Ioc5.JavaBean" init-method="init" destroy-method="destory"/>
</beans>

 测试:

package com.alphamilk.Ioc;import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class newTest {@Testpublic void test(){
//        创建容器对象ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("springioc-5.xml");/*注意,如果没有使用close函数,则会出现destroy方法无法调用的情况因为没有close下,ioc容器会意外死亡,就不会调用destroy方法*/
//        正常销毁组件对象applicationContext.close();}
}


2.1 Bean标签的作用域

什么是Bean标签的作用域

一般情况下Bean的作用域对应两种形式,单例和多例模式,以下具体讲解单例与多例。

  • 单例:一般创建Bean中默认为单例模式singleton,其意思是在测试类中getBean的时候如果只有一个对应Bean标签,那么哪怕进行多次getBean返回,返回对象都是同一个。
  • 多例:指的是在测试类中getBean的时候,在使用getBean方法的时候,虽然只有一个标签,但是每一次调用都会产生一个新的Bean组件对象。

具体创建多少个Bean的实例对象,由Bean的作用域Scope属性指定!一般都推荐用单例模式

 2.2 Scope作用域可选值

取值含义创建对象的时机默认值
singleton在 IOC 容器中,这个 bean 的对象始终为单实例IOC 容器初始化时
prototype这个 bean 在 IOC 容器中有多个实例获取 bean 时

在WebApplicationContext中较为特殊,其scope多了两个取值

取值含义创建对象的时机默认值
request请求范围内有效的实例每次请求
session会话范围内有效的实例每次会话

2.3 案例代码

创建组件类对象

package com.alphamilk.Ioc5;public class JavaBeanScope {public void doWork(){System.out.println("JavaBean is Working");}
}

配置对应单例与多例情况下

在默认情况下不需要配置scpoe

测试代码:

package com.alphamilk.Ioc;import com.alphamilk.Ioc5.JavaBeanScope;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class newTest {@Testpublic void test(){
//        创建Ioc容器ApplicationContext applicationContext = new ClassPathXmlApplicationContext("springioc-5.xml");
//        通过容器获取Bean对象JavaBeanScope bean = applicationContext.getBean(JavaBeanScope.class);JavaBeanScope bean2 = applicationContext.getBean(JavaBeanScope.class);//        结果为False,因为采用多例模式下,每一次getBean,Ioc都会new一个新的JavaBeanScope对象System.out.println(bean==bean2);}
}


二、FactoryBean接口

1.1 什么是FactoryBean

  1. 在我们前面文章中提到,实现SpringIoc有两个接口,四个实现类。Factory就是两个接口中的父接口。
  2. 虽然Ioc容器会自动new一个对象,但是并不是所有的组件都是可以随便就new出来的,比如Mybatis。其最终是要构造Session操作数据库对象,而获取该对象需要先获取配置信息getResource(配置文件),然后构造SessionFactoryBuilder,再调用SessionFactoryBuilder函数Builder,最后获取到的SessionFactory还需要调用方法openSession。这种复杂的创建对象的过程一般的Ioc容器就无法实现。所以我们直接从其根源FactoryBean来设置该如何实例化对象。

修改复杂实例化思路:

1.2  FactoryBean接口的常用方法

方法名方法描述
T getObject()返回由工厂创建的对象实例。该返回值将被存储到IoC容器中。
boolean isSingleton()如果此 FactoryBean 返回单例对象,则返回 true ,否则返回 false 。默认实现返回 true (注意,使用lombok插件可能会影响效果)。
Class<?> getObjectType()返回 getObject() 方法返回的对象类型。如果在创建之前不知道对象类型,则返回 null

1.3  实现FactoryBean案例代码

1.创建JavaBean需要实例化的子类

package com.alphamilk.Ioc6;public class JavaBean {private String name;private int age;//    组件方法public void PrintInfo(){System.out.println(name+"的年龄是"+age);}
}

2.创建JavaBean需要实例化的工厂类

package com.alphamilk.Ioc6;import org.springframework.beans.factory.FactoryBean;//泛型内容<>内填写返回的类型
public class JavaBeanFactory implements FactoryBean<JavaBean> {
//    如果子例对象需要DI(依赖注入)则需要进行桥梁连接private String name;public void setName(String name) {this.name = name;}private int age;public void setAge(int age) {this.age = age;}//    覆写如何实现实例化子类过程@Overridepublic JavaBean getObject() throws Exception {JavaBean javaBean = new JavaBean();javaBean.setAge(age);javaBean.setName(name);return javaBean;}
// 设置返回的类全定符@Overridepublic Class<?> getObjectType() {return JavaBean.class;}
}

3.配置XML

<?xml version="1.0" encoding="UTF-8"?>
<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="javaBeanFactory" class="com.alphamilk.Ioc6.JavaBeanFactory">
<!--    由于是setter注入,所以用对应的注入方法--><property name="name" value="黄飞宏"/><property name="age" value="99"/>
</bean>
</beans>

4.测试代码

package com.alphamilk.Ioc;import com.alphamilk.Ioc5.JavaBeanScope;
import com.alphamilk.Ioc6.JavaBean;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class newTest {@Testpublic void test(){
//  创建Ioc容器ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springioc-6.xml");
//        获取组件BeanJavaBean bean = (JavaBean) context.getBean("javaBeanFactory");
//        调用Bean方法测试是否有效bean.PrintInfo();}
}

总结一下FactoryBean的使用场景:

  1. 代理类的创建
  2. 第三方框架整合
  3. 复杂对象实例化等

容易混淆--面试题 FactoryBean和BeanFactory区别

  1. **FactoryBean **是 Spring 中一种特殊的 bean,可以在 getObject() 工厂方法自定义的逻辑创建Bean!是一种能够生产其他 Bean 的 Bean。FactoryBean 在容器启动时被创建,而在实际使用时则是通过调用 getObject() 方法来得到其所生产的 Bean。因此,FactoryBean 可以自定义任何所需的初始化逻辑,生产出一些定制化的 bean。
  2. 一般情况下,整合第三方框架,都是通过定义FactoryBean实现!!!
  3. BeanFactory 是 Spring 框架的基础,其作为一个顶级接口定义了容器的基本行为,例如管理 bean 的生命周期、配置文件的加载和解析、bean 的装配和依赖注入等。BeanFactory 接口提供了访问 bean 的方式,例如 getBean() 方法获取指定的 bean 实例。它可以从不同的来源(例如 Mysql 数据库、XML 文件、Java 配置类等)获取 bean 定义,并将其转换为 bean 实例。同时,BeanFactory 还包含很多子类(例如,ApplicationContext 接口)提供了额外的强大功能。
  4. 总的来说,FactoryBean 和 BeanFactory 的区别主要在于前者是用于创建 bean 的接口,它提供了更加灵活的初始化定制功能,而后者是用于管理 bean 的框架基础接口,提供了基本的容器功能和 bean 生命周期管理。

相关文章:

SpringIoC组件的高级特性

目录 一、Bean组件的周期与作用域 二、FactoryBean接口 一、Bean组件的周期与作用域 1.1 Bean组件的生命周期 什么是Bean的周期方法 我们可以在组件类中定义方法&#xff0c;然后当IoC容器实例化和销毁组件对象的时候进行调用&#xff01;这两个方法我们成为生命周期方法&a…...

Linux--进程地址空间

1.线程地址空间 所谓进程地址空间&#xff08;process address space&#xff09;&#xff0c;就是从进程的视角看到的地址空间&#xff0c;是进程运行时所用到的虚拟地址的集合。 简单地说&#xff0c;进程就是内核数据结构和代码和本身的代码和数据&#xff0c;进程本身不能…...

ISIS路由协议

骨干区域与非骨干区域 凡是由级别2组建起来的邻居形成骨干区域&#xff1b;级别1就在非骨干区域&#xff0c;骨干区域有且只有一个&#xff0c;并且需要连续&#xff0c;ISIS在IP环境下目前不支持虚链路。 路由器级别 L1路由器只能建立L1的邻居&#xff1b;L2路由器只能建立L…...

论文解读:Bert原理深入浅出

摘取于https://www.jianshu.com/p/810ca25c4502 任务1&#xff1a;Masked Language Model Maked LM 是为了解决单向信息问题&#xff0c;现有的语言模型的问题在于&#xff0c;没有同时利用双向信息&#xff0c;如 ELMO 号称是双向LM&#xff0c;但实际上是两个单向 RNN 构成的…...

共享内存 windows和linux

服务端&#xff0c;即写入端 #include <iostream> #include <string.h> #define BUF_SIZE 1024 #ifdef _WIN32 #include <windows.h> #define SHARENAME L"shareMemory" HANDLE g_MapFIle; LPVOID g_baseBuffer; #else #define SHARENAME "sh…...

一个mongodb问题分析

mongodb问题分析 现状 表的个数&#xff1a; 生产上常用的表就10来个。 sharding cluster replica set方式部署&#xff1a; 9个shard server&#xff0c; 每个shard server 1主2从&#xff0c; 大量数据写入时或对大表创建索引时&#xff0c;可能有主从复制延迟问题。实…...

Vue3.0极速入门- 目录和文件说明

目录结构 以下文件均为npm create helloworld自动生成的文件目录结构 目录截图 目录说明 目录/文件说明node_modulesnpm 加载的项目依赖模块src这里是我们要开发的目录&#xff0c;基本上要做的事情都在这个目录里assets放置一些图片&#xff0c;如logo等。componentsvue组件…...

RabbitMQ---订阅模型-Direct

1、 订阅模型-Direct • 有选择性的接收消息 • 在订阅模式中&#xff0c;生产者发布消息&#xff0c;所有消费者都可以获取所有消息。 • 在路由模式中&#xff0c;我们将添加一个功能 - 我们将只能订阅一部分消息。 例如&#xff0c;我们只能将重要的错误消息引导到日志文件…...

Django REST framework实现api接口

drf 是Django REST framework的简称&#xff0c;drf 是基于django的一个api 接口实现框架&#xff0c;REST是接口设计的一种风格。 一、 安装drf pip install djangorestframework pip install markdown # Markdown support for the browsable API. pip install …...

4.19 20

服务端没有 listen&#xff0c;客户端发起连接建立&#xff0c;会发生什么&#xff1f; 服务端如果只 bind 了 IP 地址和端口&#xff0c;而没有调用 listen 的话&#xff0c;然后客户端对服务端发起了连接建立&#xff0c;服务端会回 RST 报文。 没有 listen&#x…...

(动态规划) 剑指 Offer 10- II. 青蛙跳台阶问题 ——【Leetcode每日一题】

❓剑指 Offer 10- II. 青蛙跳台阶问题 难度&#xff1a;简单 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取模 1e97&#xff08;1000000007&#xff09;&#xff0c;如计算初始结果为&#xff1a;1…...

物联网WIFI 模块AT指令版本七大元凶

前言 目前我们讨论的这个问题&#xff0c;并不是说WIFI方案不具备以应的功能。而是指在同一个AT固件下可能存在的问题。由于各厂商AT指令的开发深度不同&#xff0c;导致各厂商之间的AT指令差异很大。我总结了一些问题&#xff0c;可能是导致目前AT指令不好用元凶。 底层库问题…...

Qt 正则(数据格式校验、替换指定格式数据、获取匹配数据)

头文件引用 #include <QRegExp>初始化QRegExp实列 QRegExp re("^\\d{1,3},\\d{1,3}$");数据格式验证 QRegExp re("^\\d{1,3},\\d{1,3}$"); QString msg "12,33"; if(re.exactMatch()){// 验证通过 }else{//验证不通过 }替换数…...

网络层协议——ip

文章目录 1. 网络层2. IP协议2.1 协议头格式 3. 网段划分3.1 特殊的IP地址3.2 IP地址的数量限制 4. 私有IP地址和公网IP地址 1. 网络层 在应用层解决了如何读取完整报文、序列化反序列化、协议处理问题。在传输层解决了可靠性问题。那么网络层IP的作用是在复杂的网络环境中确定…...

Qt6和Rust结合构建桌面应用

桌面应用程序是原生的、快速的、安全的&#xff0c;并提供Web应用程序无法比拟的体验。 Rust 是一种低级静态类型多范式编程语言&#xff0c;专注于安全性和性能&#xff0c;解决了 C/C 长期以来一直在努力解决的问题&#xff0c;例如内存错误和构建并发程序。 在桌面应用程序开…...

Kubernetes(K8S)简介

Kubernetes (K8S) 是什么 它是一个为 容器化 应用提供集群部署和管理的开源工具&#xff0c;由 Google 开发。Kubernetes 这个名字源于希腊语&#xff0c;意为“舵手”或“飞行员”。k8s 这个缩写是因为 k 和 s 之间有八个字符的关系。 Google 在 2014 年开源了 Kubernetes 项…...

面试中问:React中函数组件和class组件的区别,hooks模拟生命周期

React中函数组件和class组件的区别&#xff0c;hooks模拟生命周期 React中函数组件和class组件的区别hooks模拟生命周期 React中函数组件和class组件的区别 函数组件: 定义&#xff1a;函数组件是使用纯函数定义的组件&#xff0c;它接受 props 作为参数并返回 JSX。简洁性&am…...

Python高光谱遥感数据处理与高光谱遥感机器学习方法应用

本文提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 本文涵盖高光谱遥感的基础、方法和实践。基础篇以学员为中心&#xff0c;用通俗易懂的语言解释高光谱的基本概念和理论&#xff0c;旨在帮助学员深入理解科学原理。方法篇结合Python编程工具&#xff0c;专注…...

Java实现接收xml格式数据并解析,返回xml格式数据

需求描述&#xff1a;后端接受xml格式数据&#xff0c;解析出相应数据&#xff0c;并返回xml格式数据。 <!--XML解析--><dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>…...

【C++】初步认识模板

&#x1f3d6;️作者&#xff1a;malloc不出对象 ⛺专栏&#xff1a;C的学习之路 &#x1f466;个人简介&#xff1a;一名双非本科院校大二在读的科班编程菜鸟&#xff0c;努力编程只为赶上各位大佬的步伐&#x1f648;&#x1f648; 目录 前言一、泛型编程二、函数模板2.1 函…...

AutoUnipus:重新定义U校园学习效率的智能解决方案

AutoUnipus&#xff1a;重新定义U校园学习效率的智能解决方案 【免费下载链接】AutoUnipus U校园脚本,支持全自动答题,百分百正确 2024最新版 项目地址: https://gitcode.com/gh_mirrors/au/AutoUnipus 还在为U校园平台上堆积如山的网课任务而焦虑吗&#xff1f;每天花费…...

5分钟制作Windows启动盘:Rufus免费工具终极指南

5分钟制作Windows启动盘&#xff1a;Rufus免费工具终极指南 【免费下载链接】rufus The Reliable USB Formatting Utility 项目地址: https://gitcode.com/GitHub_Trending/ru/rufus 还在为系统重装而烦恼吗&#xff1f;Rufus作为一款完全免费的USB格式化工具&#xff0…...

从.bib到.bbl:手把手教你搞定LaTeX参考文献的完整流程

从.bib到.bbl&#xff1a;手把手教你搞定LaTeX参考文献的完整流程 如果你曾被LaTeX的参考文献格式折磨得焦头烂额&#xff0c;这篇文章就是为你准备的。我们将从零开始&#xff0c;完整走一遍从文献管理到最终PDF生成的每个步骤&#xff0c;特别关注那些让新手困惑的.bib、.bbl…...

求一个V站邀请码

有没有大佬可以给个邀请码~~~~~~~~~~~~~~~~~~...

Spring Boot项目SQL执行监控实战:手把手集成P6spy,自定义日志格式并输出到文件

Spring Boot生产环境SQL监控全方案&#xff1a;P6spy高阶配置与日志持久化实战 当你负责的电商系统在促销活动期间突然出现响应迟缓&#xff0c;或是金融交易系统在月末结算时频繁超时&#xff0c;数据库查询性能往往是首要怀疑对象。但生产环境的数据库通常不允许直接连接进行…...

微信聊天记录永久保存与智能分析:WeChatMsg完全使用指南

微信聊天记录永久保存与智能分析&#xff1a;WeChatMsg完全使用指南 【免费下载链接】WeChatMsg 提取微信聊天记录&#xff0c;将其导出成HTML、Word、CSV文档永久保存&#xff0c;对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeC…...

Python实战:用LangGraph和MCP打造你的第一个AI代理(附完整代码)

Python实战&#xff1a;用LangGraph和MCP构建智能代理的完整指南 在当今快速发展的AI领域&#xff0c;构建能够理解和执行复杂任务的智能代理已成为开发者关注的焦点。本文将带您深入了解如何利用LangGraph框架和模型上下文协议(MCP)构建一个功能完备的AI代理&#xff0c;从基础…...

机器人手臂相机 vs 抓手相机:5个关键区别与选型指南(附避坑技巧)

机器人手臂相机 vs 抓手相机&#xff1a;5个关键区别与选型指南&#xff08;附避坑技巧&#xff09; 在工业自动化领域&#xff0c;视觉引导系统如同机器人的"眼睛"&#xff0c;而相机安装位置的选择往往决定了整个系统的精度与可靠性。当工程师面对手臂相机&#xf…...

Matlab GUI 计时器:基于定时器对象自动更新的数字时钟演示

Matlab图形用户界面计时器&#xff1a;使用定时器对象自动更新的MatlabGUI&#xff0c;一个数字时钟&#xff0c;作为显示基本组件的快速演示&#xff0c;带有一个按钮&#xff0c;用于恢复/暂停执行更新实验室配了新酶标仪孵箱但总有人&#xff08;比如同组摸鱼的小师妹顺便喊…...

Simulink频域分析避坑指南:如何准确获取谐振频率(含MATLAB代码)

Simulink频域分析实战&#xff1a;谐振频率精准提取方法论与MATLAB实现 在控制系统设计与分析领域&#xff0c;频域特性是评估系统动态性能的核心指标之一。而谐振频率作为频域响应中的关键特征点&#xff0c;直接影响着系统的稳定性和响应速度。然而&#xff0c;许多工程师在使…...