Spring-bean实例化的方式

news2024/11/17 7:34:12

前言

什么是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 {
    @Override
    public 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> {
    @Override
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    @Override
    public 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.coloradmin.cn/o/2174305.html

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

相关文章

测试用例的举例

1. 基于测试公式设计测试用例 通过功能&#xff0c;性能&#xff0c;安全性&#xff0c;界面&#xff0c;安全性&#xff0c;易用&#xff0c;兼容对于一个水杯进行测试用例的设计&#xff1b; 对于一个软件的测试用例设计&#xff1a; 功能&#xff1a;软件本质上能够用来干什…

京东健康高级项目经理段一凡受邀为第四届中国项目经理大会演讲嘉宾

全国项目经理专业人士年度盛会 京东健康技术产品部高级项目经理段一凡先生受邀为PMO评论主办的全国项目经理专业人士年度盛会——2024第四届中国项目经理大会演讲嘉宾&#xff0c;演讲议题为“项目经理如何做好资源管理——货币化资源管理实践”。大会将于10月26-27日在北京举办…

C++ | 定长内存池 | 对象池

文章目录 C | 定长内存池 | 对象池一、内存池的引入二、代码中的内存池实现 - ObjectPool类&#xff08;一&#xff09;整体结构&#xff08;二&#xff09;内存分配 - New函数&#xff08;三&#xff09;内存回收 - Delete函数 三、内存池在TreeNode示例中的性能测试演示四、脱…

文件和目录

文件和目录 获取文件属性 通过 ls 命令可以查看到文件的很多属性内容&#xff0c;这些文件属性的内容可以通过以下几个函数获取: #include <sys/types.h> #include <sys/stat.h> #include <unistd.h>int stat(const char *pathname, struct stat *statbuf…

第一节- C++入门

1. &#x1f680;&#x1f680;C关键字(C98) &#x1f33c;&#x1f33c;C总计63个关键字&#xff0c;C语言32个关键字 ps&#xff1a;下面我们只是看一下C有多少关键字&#xff0c;不对关键字进行具体的讲解。后面我们学到以后再细讲。 2. 命名空间 在C/C中&#xff0c;变量…

基于深度学习的学情智能监测系统设计与实现(PYQT+YOLOv8+训练数据集+论文+部署文档)

摘要 本文设计并实现了一个基于深度学习的学情智能监测系统&#xff0c;该系统通过对学生学习状态的自动监测与分析&#xff0c;旨在辅助教师更精准地把握学生学习情况&#xff0c;进而优化教学策略和提升教学质量。在论文中&#xff0c;详细描述了系统的设计与实现过程&#…

【web开发】Spring Boot 快速搭建Web项目(三)

Date: 2024.08.31 18:01:20 author: lijianzhan 简述&#xff1a;根据上篇原文Spring Boot 快速搭建Web项目&#xff08;二&#xff09;&#xff0c;由于已经搭建好项目初始的框架&#xff0c;以及自动创建了一个启动类文件&#xff08;TestWebApplication.java&#xff09; …

一种路径敏感的数据依赖分析算法

Falcon 1.方法1.1.Basic Rule1.2.改进算法1.3.跨函数分析 2.Evaluation2.1.设置2.2.value-flow分析2.3.Thin Slicing2.4.Bug Detection 参考文献 这篇工作发表于PLDI 24&#xff0c;提出了一种context- 以semi-path-sensitive的数据依赖分析算法&#xff0c;解决path-sensitive…

如何使用ssm实现基于web的山东红色旅游信息管理系统的设计与实现

TOC ssm716基于web的山东红色旅游信息管理系统的设计与实现jsp 绪论 1.1研究背景 从古到今&#xff0c;信息的录入&#xff0c;存储&#xff0c;检索都受制于社会生产力的发展&#xff0c;不仅仅浪费大量的人力资源还需要浪费大量的社会物资&#xff0c;并且不能长时间的保…

信息安全工程师(24)网络安全体系建设原则与安全策略

一、网络安全体系建设原则 网络空间主权原则&#xff1a;维护网络空间主权是网络安全的首要原则。这要求国家在网络空间的管理、运营、建设和使用等方面具有完全自主的权利和地位&#xff0c;不受任何外部势力的干涉和侵犯。网络安全与信息化发展并重原则&#xff1a;网络安全与…

Midjourney 使用教程——入门篇

目录标题 一、前提二、Midjourney 使用文档三、如何注册使用Midjourney四、结合GPT快速生成Midjourney 构图指令五、其他 一、前提 先连接国外代理服务器。没有的可以退下了。 二、Midjourney 使用文档 Discord 快速入门 注意&#xff1a;如图所示&#xff0c;需要10美刀一…

【HTML5】html5开篇基础(4)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

已解决:“ModuleNotFoundError:No module named apex”

首先遇到这个问题不可以直接简单粗暴的使用&#xff1a;“pip install apex”直接安装模块来解决&#xff0c;这样的话程序还是会继续报错“ModuleNotFoundError&#xff1a;No module named apex”&#xff0c;别问我怎么知道&#xff0c;问就是深受其害&#xff01; 去网上查…

Android实现图片滚动和页签控件功能的实现代码

首先题外话&#xff0c;今天早上起床的时候&#xff0c;手滑一下把我的手机甩了出去&#xff0c;结果陪伴我两年半的摩托罗拉里程碑一代就这么安息了&#xff0c;于是我今天决定怒更一记&#xff0c;纪念我死去的爱机。 如果你是网购达人&#xff0c;你的手机上一定少不了淘宝…

热题系列章节21

补充题14. 阿拉伯数字转中文数字 补充题9. 36进制加法 85. 最大矩形 class Solution:def maximalRectangle(self, matrix: List[List[str]]) -> int:if not matrix:return 0m,nlen(matrix),len(matrix[0])# 记录当前位置上方连续“1”的个数pre[0]*(n1)res0for i in range…

带你0到1之QT编程:二十、QT与MySQL喜结连理,构建数据库应用开发

此为QT编程的第二十谈&#xff01;关注我&#xff0c;带你快速学习QT编程的学习路线&#xff01; 每一篇的技术点都是很很重要&#xff01;很重要&#xff01;很重要&#xff01;但不冗余&#xff01; 我们通常采取总-分-总和生活化的讲解方式来阐述一个知识点&#xff01; …

基于elasticsearch存储船舶历史轨迹

文章目录 引言轨迹文档定时创建索引手动添加索引并为索引添加别名POST请求批量插入文档数据查询文档数据引言 需求: 存储轨迹,提供站点查询显示 实现:每天创建索引,使用POST请求往Elasticsearch批量插入文档数据 依赖 <dependency><groupId>org.springframe…

JAVA红娘婚恋相亲交友系统源码全面解析

在数字化时代&#xff0c;红娘婚恋相亲交友系统成为了连接单身男女的重要桥梁。JAVA作为一种流行的编程语言&#xff0c;为开发这样的系统提供了强大的支持。编辑h17711347205以下是对JAVA红娘婚恋相亲交友系统源码的全面解析&#xff0c;以及三段示例代码的展示。 系统概述 …

Stable Diffusion绘画 | 插件-Deforum:动态视频生成

Deforum 与 AnimateDiff 不太一样&#xff0c; AnimateDiff 是生成丝滑变化视频的&#xff0c;而 Deforum 的丝滑程度远远没有 AnimateDiff 好。 它是根据对比前面一帧的画面&#xff0c;然后不断生成新的相似图片&#xff0c;来组合成一个完整的视频。 Deforum 的优点在于可…

DevExpress WPF中文教程:如何解决编辑单元格值的常见问题?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…