Spring-bean实例化的方式

前言

什么是bean的实例化?

通常我们使用spring管理java的对象,一般称这个java对象为一个实例化的bean。bean的实例化方式,实际上就是spring创建并管理java对象实例的方式

 bean的实例化方式

在Java和Spring框架的上下文中,Bean的实例化是指创建Java对象(Bean)的过程。这个过程涉及到将Java类的定义(即类的字节码)转换成内存中实际可用的对象实例。在Spring框架中,Bean的实例化是Spring容器(也称为IoC容器)管理对象生命周期的一部分,它负责创建、配置、组装和管理这些对象。

Spring容器通过几种不同的方式来实例化Bean,包括但不限于以下几种:

1. 构造方法实例化

  • 方式描述:通过调用Java Bean类的构造方法来创建对象。默认情况下,Spring会调用Bean的无参数构造方法。如果Bean类中有多个构造方法,可以通过配置指定使用哪个构造方法,或者通过构造方法注入依赖。
  • 应用场景:适用于大多数简单的Bean实例化场景,特别是当Bean的创建不依赖于其他Bean或复杂逻辑时。

2. 静态工厂方法实例化

  • 方式描述:通过调用静态工厂方法来创建Bean实例。这种方式需要在Spring配置文件中指定工厂类的静态方法。
  • 应用场景:当Bean的创建过程比较复杂,或者Bean的创建依赖于一些静态的、不需要实例化的资源时,可以使用静态工厂方法。

3. 实例工厂方法实例化

  • 方式描述:通过调用实例工厂的方法来创建Bean实例。这种方式需要首先创建工厂Bean的实例,然后通过该实例的方法来创建目标Bean。
  • 应用场景:当Bean的创建依赖于其他Bean的实例时,或者当Bean的创建过程需要复杂的逻辑处理时,可以使用实例工厂方法。

4. Spring的FactoryBean接口实例化

  • 方式描述:通过实现Spring的FactoryBean接口来创建Bean实例。FactoryBean接口提供了getObject()方法,Spring容器在调用该方法时返回Bean实例。这种方式允许开发者在Bean的创建过程中进行更复杂的操作,如懒加载、代理创建等。
  • 应用场景:当需要更细粒度的控制Bean的创建过程,或者需要返回Bean的代理对象时,可以使用FactoryBean接口。

5. 反射实例化(非Spring特有)

  • 方式描述:使用Java反射机制来实例化Java Bean对象。通过Class类的newInstance()方法或Constructor类的newInstance()方法可以动态创建对象。
  • 应用场景:在不需要Spring框架的情况下,或者当需要动态地根据类名创建对象时,可以使用反射实例化。

小结

Bean的实例化方式多种多样,每种方式都有其特定的应用场景和优势。在实际开发中,应根据具体需求和开发环境选择合适的实例化方式。同时,随着Spring框架的不断发展,未来还可能出现更多新的实例化方式。

 bean的四种实例化方式的案例演示

bean本质上是一个对象,是spring操作类的构造方法创建的(不论这个构造方法是私有还有共有),底层通过反射完成;并且调用的是无参的构造方法。

 准备工作

创建一个maven项目,导入spring相关依赖包

<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>

 在resources中配置spring配置文件


<?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"></beans>

构造方法实例化bean

创建一个UserDao和它的实现类

UserDao

package com.csx.dao;public interface UserDao {public void say();
}

UserDaoImpl

package com.csx.dao.impl;import com.csx.dao.UserDao;public class UserDaoImpl implements UserDao {@Overridepublic void say() {System.out.println("User实现类执行中...");}
}

spring.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="userDao" class="com.csx.dao.impl.UserDaoImpl"/></beans>

APP

package com.csx;import com.csx.dao.UserDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class APP {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");UserDao userDao = (UserDao) context.getBean("userDao");userDao.say();}
}

此时采用默认的无参构造来创建UserDaoImpl对象,交给IOC容器管理,如果此时没有无参构造,则创建失败。

 创建一个属性,并创建一个构造,导致默认的无参构造失效,则程序运行失败。

注意:构造方法可以写也可以不写(系统默认给无参构造方法),但是一旦写了构造方法,一定要书写无参的构造方法。

 静态工厂实例化bean

使用工厂实例化bean(早期一些项目中使用,目的是为了解耦),即创造对象不直接new,而是通过工厂的方式获取对象

 

创建工厂类,

注意:工厂中实例化对象的方法是静态的。

UserStaticFactory

package com.csx.factory;import com.csx.dao.UserDao;
import com.csx.dao.impl.UserDaoImpl;public class UserStaticFactory {public static UserDao getUserDao(){return new UserDaoImpl();}
}

工厂类的spring.xml的配置文件设置

spring.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="userDao" class="com.csx.dao.impl.UserDaoImpl"/>--><bean id="userDao" class="com.csx.factory.UserStaticFactory" factory-method="getUserDao"/></beans>

id:工厂类的别名

class:配置工厂类的全限定名

factory-method:工厂类中的静态方法名

 APP

public class APP {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");UserDao userDao = (UserDao) context.getBean("userDao");userDao.say();}
}

实例工厂实例化bean

UserFactory

package com.csx.factory;import com.csx.dao.UserDao;
import com.csx.dao.impl.UserDaoImpl;public class UserFactory {public UserDao getUserDao(){return new UserDaoImpl();}
}

实例工厂中的方式是实例的,不是静态的,因此配置文件中的bean配置也有一些区别

 spring.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="userDao" class="com.csx.dao.impl.UserDaoImpl"/>--><!--    <bean id="userDao" class="com.csx.factory.UserStaticFactory" factory-method="getUserDao"/>--><bean id="userFactory" class="com.csx.factory.UserFactory"/><bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
</beans>

 APP

public class APP {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");UserDao userDao = (UserDao) context.getBean("userDao");userDao.say();}
}

 实现FactoryBean接口的方式实例化

本质上是对实例工厂实例化bean的一种简化,我们可以看到:

因为实例工厂实例化bean的方式,需要创建一个工厂类对象,但这个对象只在实例化bean的时候使用一次,spring针对这个方式进行了改良。目的是为了简化配置。

 UserFactoryBean

创建一个类实现FactoryBean接口,泛型为想要管理的接口类

public class UserFactoryBean implements FactoryBean<UserDao> {@Overridepublic UserDao getObject() throws Exception {return new UserDaoImpl();}@Overridepublic Class<?> getObjectType() {return UserDao.class;}
}

spring.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="userDao" class="com.csx.dao.impl.UserDaoImpl"/>--><!--    <bean id="userDao" class="com.csx.factory.UserStaticFactory" factory-method="getUserDao"/>-->
<!--    <bean id="userFactory" class="com.csx.factory.UserFactory"/>--><!--    <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>--><bean id="userDao" class="com.csx.factory.UserFactoryBean"/>
</beans>

此时spring.xml的配置可以直接管理工厂类

 APP

public class APP {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring.xml");UserDao userDao = (UserDao) context.getBean("userDao");userDao.say();}
}

总结

spring实例化bean的方式,实际上就是spring创建并管理java对象的方式,主要使用反射机制,调用无参构造方法实现。至于静态工厂和实例化工厂创建bean的方式,是为了兼容一些老的项目而采用的方式,目的是为了解耦。 

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

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

相关文章

医院安保巡更管理应用二维码无纸化巡更方式

医院安保巡查是维护医院秩序安全的重中之重&#xff0c;在确保医院的安全运行&#xff0c;预防和减少安全事故的发生。通过定期的安全巡查&#xff0c;可以及时发现和解决潜在的安全隐患&#xff0c;保障医护人员和患者的安全。例如&#xff1a;‌安全疏散通道、‌监控设备‌、…

ACDsee简体中文版网盘资源下载(含教程)

如大家所熟悉的&#xff0c;ACDSee是一款集看图、编辑和管理于一体的软件&#xff0c;其凭借着打开速度快、管理功能强、操作界面友好简单等等优势&#xff0c;广受用户的喜欢。目前最新为ACDSee 2024版本。 一、文件管理 ACDSee数据库在文件管理方面表现出色。它可以帮助用户…

四气两尘监测站中空气质量传感器推荐

在快速发展的工业化进程中&#xff0c;空气质量已成为衡量一个地区环境健康水平的重要指标。随着公众环保意识的增强&#xff0c;对空气质量的关注不再局限于直观的蓝天白云&#xff0c;而是深入到更为细微、复杂的污染物层面&#xff0c;其中&#xff0c;“四气两尘”便是这一…

操作平台使用中应每月不少于几次定期检查?

在当今数字化时代&#xff0c;操作平台作为企业与个人日常运营的核心载体&#xff0c;其稳定性和安全性直接关系到业务的高效运行与数据的严密保护。因此&#xff0c;定期进行操作平台的检查与维护&#xff0c;成为了不可忽视的重要环节。特别是&#xff0c;确保每月进行不少于…

JAVA的版本

Java的版本开始还正常&#xff1a;1.0 ->1.1 顺序增加&#xff0c;到了2004年&#xff0c;不知什么原因1.5又有了新的平行名字5&#xff0c;这样Java 1.6对应Java6&#xff0c;一直到Java1.8 对应 Java8&#xff0c;然后到在2017年彻底没了Java1.9,只有Java9了。好吧这可以忍…

【初阶数据结构】排序——选择排序

目录 前言选择排序堆排序 前言 对于常见的排序算法有以下几种&#xff1a; 下面这节我们来看选择排序算法。 选择排序 基本思想&#xff1a;   每一次从待排序的数据元素中遍历选出最大&#xff08;或最小&#xff09;的元素放在序列的起始位置&#xff0c;直到全部待排序…

828华为云征文 | 使用 Memtester 对华为云 X 实例进行内存性能测试

目录 前言 1 华为云X实例介绍 2 Memtester 简介 2.1 什么是Memtester 2.2 安装 Memtester 3 测试方案设计 3.1 测试目标 3.2 测试环境 3.3 测试命令 4 测试数据及性能分析 4.1 带宽测试结果 4.2 延迟测试结果 5 性能瓶颈与优化建议 6 总结 前言 在云计算的应用场…

从0学习React(2)

经过上一篇的文章&#xff0c;对index.tsx文件的每行代码进行了一个简单的分析之后&#xff0c;我大概对React有了一个简单的了解。虽然也是一知半解&#xff0c;但是起码在心里已经对React有了一个基本的概念。这篇文章&#xff0c;我就讲一下关于React中index.tsx的大致框架。…

以太网交换安全:端口安全

一、端口安全介绍 端口安全是一种网络设备防护措施&#xff0c;通过将接口学习到的动态MAC地址转换为安全MAC地址&#xff08;包括安全动态MAC和Sticky MAC&#xff09;&#xff0c;阻止除安全MAC和静态MAC之外的主机通过本接口和设备通信&#xff0c;从而增强设备的安全性。以…

【运维资料】系统运维管理方案(Doc原件2024)

1 编制目的 2 系统运行维护 2.1 系统运维内容 2.2 日常运行维护方案 2.2.1 日常巡检 2.2.2 状态监控 2.2.3 系统优化 2.2.4 软件系统问题处理及升级 2.2.5 系统数据库管理维护 2.2.6 灾难恢复 2.3 应急运行维护方案 2.3.1 启动应急流程 2.3.2 成立应急小组 2.3.3 应急处理过程 …

产品管理 - 互联网产品(3) : 迭代管理

1、需求文档的每一个迭代版本号&#xff0c;都需要标识出来 根据软件文档的配置标准&#xff1a; 上线时&#xff1a;X.Y 修改时&#xff1a;X.YZ 草稿时&#xff1a;0.XY 2、每一个项目干系人&#xff0c;都可以访问到最新版本的需求。 所有角色必须要有统的一认知。这是需求…

【Canvas与诗词】秋夕.杜牧(银烛秋光冷画屏......)

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>金六边形外圈绿色底录杜牧秋夕诗</title><style type"…

PHP爬虫:获取商品销量详情API的利器

在电子商务时代&#xff0c;商品的销量数据对于商家来说至关重要。它不仅能够帮助商家了解市场动态&#xff0c;还能够指导库存管理和营销策略。PHP作为一种流行的服务器端脚本语言&#xff0c;结合其强大的HTTP请求处理能力&#xff0c;可以有效地用于编写爬虫程序&#xff0c…

Defining Smart Contract Defects on Ethereum论文解读

背景 这一部分介绍了智能合约的概念和基础知识&#xff0c;以及 Solidity 编程语言。 智能合约&#xff1a;定义了智能合约作为一种运行在区块链上的程序&#xff0c;它能够在无需第三方干预的情况下自动执行合同条款。智能合约的不可变性&#xff1a;强调了智能合约一旦部署…

Python in Excel作图分析实战!

Excel 中的 Python 现已正式发布&#xff0c;适用于 Microsoft 365 商业版和企业版的 Windows 用户。去年 8 月&#xff0c;微软与 Anaconda 合作&#xff0c;通过集成 Python 为 Excel 引入了一个令人兴奋的新增功能&#xff0c;从而可以将 Python 和 Excel 分析无缝结合到同一…

开放原子开源基金会网站上的开源项目Opns存在缓冲区溢出缺陷

最近在开放原子开源基金会网站上&#xff0c;看到一些开源项目&#xff0c;之前分析出华为的鸿蒙操作系统代码&#xff0c;没有发现有价值的安全漏洞。现在&#xff0c;下载上面的Onps开源网络协议栈&#xff0c;既然是通讯所使用的软件&#xff0c;其质量应该值得信任呢&#…

MySQL - 进阶篇

一、存储引擎 1. MySQL体系结构 2. 存储引擎简介 3. 存储引擎特点 4. 存储引擎选择 二、索引 1. 索引概述 2. 索引结构 3. 索引分类 4. 索引语法 5. SQL性能分析 6. 索引使用 7. 索引设计原则 三、SQL优化 1. 插入数据 2. 主键优化 3. order by优化 4. group by优化 5. limi…

【JavaEE】——线程池大总结

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c; 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01;希望本文内容能够帮助到你&#xff01; 目录 引入&#xff1a;问题引入 一&#xff1a;解决方案 1&#xff1a;方案一——协程/纤程 &#xff08;1…

CST仿真分析:圆柱形谐振腔的模式分析

波导谐振器一般可以由波导两端短路形成&#xff0c;矩形和圆柱形谐振腔比较常见。矩形谐振腔模式的表示&#xff0c;是从波导的TEmn和TMmn变成了TEmnp和TMmnp&#xff0c;p是沿z方向的周期。之所以我们这里分析圆柱形&#xff0c;一是三个下角标更不容易理解&#xff08;TEnip和…

七段 LED 显示器(7段数码管)

7 段 LED 显示器, 通常简称为 LED 数码管 或 数码管. 通过 菜单--绘制--数字芯片--添加 7 段 LED 显示器 可以引入它. 普通模式 它内部其实就是七盏长条状的 LED 灯, 有的横着放, 有的竖着放. 七个灯用 a b c d e f g 分别表示. 灯的位置从上到下, 从里到外顺时针下来, 如上图…