【Spring】Bean 的实例化方式

news2024/11/25 10:48:18

Spring 为 Bean 提供了多种实例化方式,通常包括4种方式

也就是说在 Spring 中为 Bean 对象的创建准备了多种方案,目的是:更加灵活

  • 第一种:通过构造方法实例化

  • 第二种:通过简单工厂模式实例化

  • 第三种:通过 factory-bean 实例化

  • 第四种:通过 FactoryBean 接口实例化

 

一、通过构造方法实例化 

public class SpringBean {
    public SpringBean(){
        System.out.println("SpringBean 的无参数构造方法执行.......");
    }
}
<!--
    Spring 提供的实例化方式
        第一种:在Spring配置文件中直接配置类全路径,Spring会自动调用该类的无参数构造方法来实例化Bean
-->
<bean id="springBean" class="org.qiu.spring.bean.SpringBean"/>
@Test
public void testInstantiationOne(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    SpringBean springBean = applicationContext.getBean("springBean", SpringBean.class);
    System.out.println(springBean);
}

运行结果: 

 

二、通过简单工厂模式实例化 

public class Star {
    public Star(){
        System.out.println("Star 的无参数构造方法执行......");
    }
}
public class StarFactory {
    public static Star get(){
        // 这个 Star 实际上创建的时候还是我们自己 new 的对象
        return new Star();
    }
}
<!--
    Spring 提供的实例化方式
        第二种:简单工厂模式。需要在Spring配置文件中告诉Spring框架,调用哪个类的哪个方法获取Bean
        factory-method : 指定工厂类中的静态方法,告诉Spring框架,调用这个方法可以获取Bean
-->
<bean id="starBean" class="org.qiu.spring.bean.StarFactory" factory-method="get"/>
@Test
public void testtestInstantiationTwo(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Star star = applicationContext.getBean("starBean", Star.class);
    System.out.println(star);
}

运行结果:

 

三、通过 factory-bean 实例化

这种方式本质上是:通过工厂方法模式进行实例化  

public class Gun{
    public Gun() {
        System.out.println("Gun 的无参数构造方法执行......");
    }
}
public class GunFactory{
    public Gun get(){
        return new Gun();
    }
}
<!--
    Spring 提供的实例化方式
        第三种:通过工厂方法模式
-->
<bean id="gunFactory" class="org.qiu.spring.bean.GunFactory"/>
<bean id="gun" factory-bean="gunFactory" factory-method="get"/>
@Test
public void testtestInstantiationThree(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Gun gun = applicationContext.getBean("gun", Gun.class);
    System.out.println(gun);
}

运行结果:

 

四、通过 FactoryBean 接口实例化 

以上的第三种方式中,factory-bean 是我们自定义的,factory-method 也是我们自己定义的

在 Spring 中,当你编写的类直接实现 FactoryBean 接口之后,factory-bean 不需要指定了,factory-method 也不需要指定了

factory-bean 会自动指向实现 FactoryBean 接口的类,factory-method 会自动指向 getObject() 方法

package org.qiu.spring.bean;

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:15
 * @since 1.0
 */
public class Person {
    public Person() {
        System.out.println("Person 的无参数构造方法执行......");
    }
}
package org.qiu.spring.bean;

import org.springframework.beans.factory.FactoryBean;

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:16
 * @since 1.0
 */
public class PersonFactoryBean implements FactoryBean<Person> {
    @Override
    public Person getObject() throws Exception {
        // 最终这个 Bean 的创建还是程序员自己 new 的
        return new Person();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }

    /**
     * 这个方法 FactoryBean 接口有默认实现
     *      default boolean isSingleton() {
     *          return true;
     *      }
     * 即获取的 Bean 默认情况下是单例的
     * 若需要修改为多例,修改为 return false 即可
     */
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}
<!--
    Spring 提供的实例化方式
        第四种:通过 FactoryBean 接口来实现,实际上简化了第三种方式
        通过 factoryBean 这个工厂 Bean 主要是想对普通 Bean 进行加工处理
-->
<bean id="personBean" class="org.qiu.spring.bean.PersonFactoryBean"/>
@Test
public void testInstantiationFour(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Person personBean = applicationContext.getBean("personBean", Person.class);
    System.out.println(personBean);

    Person personBean2 = applicationContext.getBean("personBean", Person.class);
    System.out.println(personBean2);
}

运行结果:

FactoryBean 在 Spring 中是一个接口,被称为 “工厂Bean”。“工厂Bean”是一种特殊的 Bean。所有的“工厂Bean”都是用来协助Spring 框架来创建其他 Bean 对象的

 

五、BeanFactory 和 FactoryBean 的区别 

BeanFactory:

Spring IoC 容器的顶级对象,BeanFactory 被翻译为“Bean工厂”,在 Spring 的 IoC 容器中,“Bean工厂”负责创建 Bean 对象

BeanFactory 是工厂


FactoryBean:

FactoryBean:它是一个Bean,是一个能够辅助 Spring 实例化其它 Bean 对象的一个 Bean

在 Spring 中,Bean可以分为两类:

  • 第一类:普通 Bean

  • 第二类:工厂 Bean(记住:工厂 Bean 也是一种 Bean,只不过这种 Bean 比较特殊,它可以辅助 Spring 实例化其它 Bean 对象)

 

六、注入自定义 Date 

前面说过,java.util.Date 在 Spring 中被当做简单类型,简单类型在注入的时候可以直接使用 value 属性或 value 标签来完成。但我们之前已经测试过了,对于 Date 类型来说,采用 value 属性或 value 标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022,其他格式是不会被识别的。如以下代码:  

package org.qiu.spring.bean;

import java.util.Date;

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:34
 * @since 1.0
 */
public class Student {
    private Date birth;

    public void setBirth(Date birth) {
        this.birth = birth;
    }

    @Override
    public String toString() {
        return "Student{" +
                "birth=" + birth +
                '}';
    }
}
package org.qiu.spring.bean;

import org.springframework.beans.factory.FactoryBean;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author 秋玄
 * @version 1.0
 * @email qiu_2022@aliyun.com
 * @project Spring
 * @package org.qiu.spring.bean
 * @date 2022-11-10-22:41
 * @since 1.0
 */
public class DateFactoryBean implements FactoryBean<Date> {

    private String strDate;

    public DateFactoryBean(String strDate) {
        this.strDate = strDate;
    }

    @Override
    public Date getObject() throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(strDate);
        return date;
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}
<!--
    1、将 value 的值通过 DateFactoryBean 的构造方法 DateFactoryBean(String strDate) 赋值给 DateFactoryBean 的 date 属性
    2、DateFactoryBean 实现了 FactoryBean 接口,Spring 会自动调用 getObject 方法
    3、getObject 中对第一步注入的字符串(date字符串)进行格式化并返回一个自定义格式的 Date 对象
    4、将上一步的 Date 对象注入给 Student 这个 Bean 的 birth 属性
-->
<bean id="date" class="org.qiu.spring.bean.DateFactoryBean">
    <constructor-arg index="0" value="2000-01-01"/>
</bean>

<bean id="student" class="org.qiu.spring.bean.Student">
    <property name="birth" ref="date"/>
</bean>
@Test
public void testDate(){
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
    Student student = applicationContext.getBean("student", Student.class);
    System.out.println(student);
}

运行结果: 

 

一  叶  知  秋,奥  妙  玄  心

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

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

相关文章

【九章斩题录】Leetcode:判定是否互为字符重排(C/C++)

面试题 01.02. 判定是否互为字符重排 ✅ 模板&#xff1a;C class Solution { public:bool CheckPermutation(string s1, string s2) {} }; 「 法一 」排序 &#x1f4a1; 思路&#xff1a;看到题目中说 "重新排列后能否变成另一个字符串"&#xff0c;等等……重新…

读书笔记之《重塑大脑重塑人生》:大脑强大的可塑性

《重塑大脑重塑人生》作者是诺曼道伊奇&#xff0c;原作名: The Brain That Changes Itself: Stories of Personal Triumph from the Frontiers of Brain Science &#xff0c;于 2015-1-20出版。 诺曼•道伊奇&#xff08;Norman Doidge&#xff09;是医学博士&#xff0c;精…

python + numpy test

1. 2. What is the correct syntax to output the type of a variable or object in Python? Syntax of the Python type() functionThe type() function 3. upper() 全大写 lower() 全小写 4. 接下来是Numpy部分 1. What is a correct syntax to check the number of di…

图(高阶数据结构)

目录 一、图的基本概念 二、图的存储结构 2.1 邻接矩阵 2.2 邻接表 三、图的遍历 3.1 广度优先遍历 3.2 深度优先遍历 四、最小生成树 4.1 Kruskal算法 4.2 Prim算法 五、最短路径 5.1 单源最短路径-Dijkstra算法 5.2 单源最短路径-Bellman-Ford算法 5.3 多源最…

一个基于 .NET 7 + Vue.js 的前后端分离的通用后台管理系统框架 - DncZeus

前言 今天给大家推荐一个基于.NET 7 Vue.js(iview-admin) 的前后端分离的通用后台权限(页面访问、操作按钮控制)管理系统框架&#xff1a;DncZeus。 官方项目简介 DncZeus是一个基于 .NET 7 Vue.js 的前后端分离的通用后台管理系统框架。后端使用.NET 7 Entity Framework…

Qt视频播放器项目

一.创建项目 二.设计UI 按钮与名称的对应 打开视频按钮 -> pushButton_Open 播放按钮 -> pushButton_Play 暂停按钮 -> pushButton_Pause 停止按钮 -> pushButton_Stop 音量按钮 -> pushButton_Sound设置图标 在项目目录下创建images文件夹&#xff0c;把图标…

计算机毕业设计SSM基于的奶茶店预约订单系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; vue mybatis Maven mysql5.7或8.0等等组成&#xff0c;B…

Java实现固始鹅块销售系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 鹅块类型模块2.3 固始鹅块模块2.4 鹅块订单模块2.5 评论管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 鹅块类型表3.2.2 鹅块表3.2.3 鹅块订单表3.2.4 鹅块评论表 四、系统展示五、核心代码5.…

13 年后,我如何用 Go 编写 HTTP 服务(译)

原文&#xff1a;Mat Ryer - 2024.02.09 大约六年前&#xff0c;我写了一篇博客文章&#xff0c;概述了我是如何用 Go 编写 HTTP 服务的&#xff0c;现在我再次告诉你&#xff0c;我是如何写 HTTP 服务的。 那篇原始的文章引发了一些热烈的讨论&#xff0c;这些讨论影响了我今…

Python静态方法和类方法的区别和应用

实际上&#xff0c;Python 完全支持定义类方法&#xff0c;甚至支持定义静态方法。Python 的类方法和静态方法很相似&#xff0c;它们都推荐使用类来调用&#xff08;其实也可使用对象来调用&#xff09;。 类方法和静态方法的区别在于&#xff0c;Python会自动绑定类方法的第…

【【C++类与对象(下)】】

1. 再谈构造函数 构造函数体赋值 在创建对象时&#xff0c;编译器会通过调用构造函数&#xff0c;给对象中的各个成员变量一个合适的初始值&#xff1a; class Date { public:// 构造函数Date(int year 0, int month 1, int day 1){_year year;_month month;_day day;}…

Acwing---836. 合并集合

合并集合 1.题目2.基本思想3.代码实现 1.题目 一共有 n n n 个数&#xff0c;编号是 1 ∼ n 1∼n 1∼n&#xff0c;最开始每个数各自在一个集合中。 现在要进行 m m m 个操作&#xff0c;操作共有两种&#xff1a; M a b&#xff0c;将编号为 a a a 和 b b b 的两个数所…

Netty应用(二) 之 ByteBuffer

目录 4.ByteBuffer详解 4.1 ByteBuffer为什么做成一个抽象类&#xff1f; 4.2 ByteBuffer是抽象类&#xff0c;他的主要实现类为 4.3 ByteBuffer的获取方式 4.4 核心结构&#xff08;NIO的ByteBuffer底层是啥结构&#xff0c;以及读写模式都是根据这些核心结构进行维护的&a…

【JavaScript 漫游】【014】正则表达式通关

文章简介 JS 语言中的 RegExp 对象提供正则表达式的功能。本篇文章旨在对该对象的相关知识点进行总结。内容包括&#xff1a; 正则表达式概述RegExp 对象的实例属性RegExp 对象的实例方法字符串与正则表达式相关的实例方法正则表达式匹配规则 概述 正则表达式的概念 正则表…

linux 08 文件查找

02. 第一. alias 第二. locate&#xff1a; locate 找不到最近的文件 更新locate 后

Spring Cloud Hystrix 参数配置、简单使用、DashBoard

Spring Cloud Hystrix 文章目录 Spring Cloud Hystrix一、Hystrix 服务降级二、Hystrix使用示例三、OpenFeign Hystrix四、Hystrix参数HystrixCommand.Setter核心参数Command PropertiesFallback降级配置Circuit Breaker 熔断器配置Metrix 健康统计配置Request Context 相关参数…

Flink 2.0 状态存算分离改造实践

本文整理自阿里云智能 Flink 存储引擎团队兰兆千在 FFA 2023 核心技术&#xff08;一&#xff09;中 的分享&#xff0c;内容关于 Flink 2.0 状态存算分离改造实践的研究&#xff0c;主要分为以下四部分&#xff1a; Flink 大状态管理痛点 阿里云自研状态存储后端 Gemini 的存…

基于Java (spring-boot)的考勤管理系统

一、项目介绍 普通员工功能&#xff1a; &#xff08;1&#xff09;登录&#xff1a;员工进入界面后需要输入自己的账号密码进行登录。 &#xff08;2&#xff09;签到打卡&#xff1a;员工登录完成以后&#xff0c;可以进行签到打卡。 &#xff08;3&#xff09;修改密码&a…

mac卸载被锁定的app

sudo chflags -hv noschg /Applications/YunShu.app 参考&#xff1a;卸载云枢&#xff08;MacOS 版&#xff09;

从左值和右值的角度分析a++和++a

摘自牛客上的一个题目&#xff1a; int a5,则 (a)的值是? 答案是会编译报错。 原因&#xff1a; a返回的是右值(rvalue)&#xff0c;而我们不能对一个右值进行自增操作。所以(a)会报错。 怎么理解呢&#xff1f; &#xff08;a)返回的是a在1之前的值&#xff0c;这个值是一个…