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

【Spring6】| Bean的四种获取方式(实例化)

目录

一:Bean的实例化方式

1. 通过构造方法实例化

2. 通过简单工厂模式实例化

3. 通过factory-bean实例化

4. 通过FactoryBean接口实例化

5. BeanFactory和FactoryBean的区别(面试题)

6. 使用FactoryBean注入自定义Date


一:Bean的实例化方式

Spring为Bean提供了多种实例化方式,通常包括4种方式。(也就是说在Spring中为Bean对象的创建准备了多种方案,目的是:更加灵活)

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

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

第三种:通过factory-bean实例化(工厂方法模式)

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

1. 通过构造方法实例化

我们之前一直使用的就是这种方式!默认情况下,会调用Bean的无参数构造方法,这里在复习一遍!

SpringBean类

package com.bjpowernode.spring.bean;public class SpringBean {public SpringBean() {System.out.println("SpringBean的无参数构造方法执行了");}
}

spring.xml配置

第一种:在spring配置文件中直接配置类全路径,Spring会自动调用该类的无参数构造方法来实例化Bean!

<?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"><!--Spring提供的实例化方式,第一种--><bean id="sb" class="com.bjpowernode.spring.bean.SpringBean"/>
</beans>

BeanInstantiationTest测试类

package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.SpringBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest {@Testpublic void tesInstantiation1(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");SpringBean sb = applicationContext.getBean("sb", SpringBean.class);System.out.println(sb);}
}

执行结果:成功调用无参数构造方法实例化对象

2. 通过简单工厂模式实例化

简单工厂模式又叫做静态工厂方法模式,因为工厂类中有一个静态方法!

第一步:定义一个Bean

package com.bjpowernode.spring.bean;public class Vip {public Vip() {System.out.println("我是一个Vip");}
}

第二步:编写简单工厂模式当中的工厂类

package com.bjpowernode.spring.bean;public class VipFactory {// 里面有一个静态方法public static Vip get(){// 实际上对象的创建还是我们程序员自己完成的return new Vip();}
}

第三步:在Spring配置文件中指定创建该Bean的方法

第二种:通过简单工厂模式。

需要在Spring配置文件中告诉Spring框架,调用哪个类哪个方法获取Bean?

class属性指定的是工厂类的全限定类名

factory-method属性指定的是工厂类当中的静态方法,也就是告诉Spring框架,调用这个方法可以获取Bean!

<?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"><!--Spring提供的实例化方式,第二种--><bean id="vipBean" class="com.bjpowernode.spring.bean.VipFactory" factory-method="get"/>
</beans>

第四步:编写测试程序

package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.SpringBean;
import com.bjpowernode.spring.bean.Vip;
import com.bjpowernode.spring.bean.VipFactory;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest {@Testpublic void tesInstantiation2(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Object vipBean = applicationContext.getBean("vipBean", Vip.class);System.out.println(vipBean);}
}

执行结果:通过简单工厂模式也能实例化对象

3. 通过factory-bean实例化

本质上是:通过工厂方法模式进行实例化对象!

注:简单工厂模式和工厂方法模式的区别

①简单工厂模式是所有的产品对应一个工厂类,使用的是静态方法!

②工厂方法模式是一个产品对应一个工厂类,使用的是实例方法!

第一步:定义一个Bean

package com.bjpowernode.spring.bean;
// 工厂方法模式当中的:具体产品角色
public class Gun {public Gun() {System.out.println("Gun的无参数构造方法执行");}
}

第二步:定义具体工厂类,工厂类中定义实例方法

package com.bjpowernode.spring.bean;
// 工厂方法模式当中:的具体工厂角色
public class GunFactory {// 实例方法public Gun get(){// 还是我们自己new的对象return new Gun();}}

第三步:在Spring配置文件中指定factory-bean以及factory-method

第三种:通过工厂方法模式。

通过 factory-bean属性 + factory-method属性来共同完成。告诉Spring框架,调用哪个对象(因为是实例方法需要创建对象)的哪个方法来获取Bean。

factory-bean属性用来告诉Spring调用那个对象

factory-method属性用来告诉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"><!--Spring提供的实例化方式,第三种--><bean id="gunBean" class="com.bjpowernode.spring.bean.GunFactory"/><bean id="gun" factory-bean="gunBean" factory-method="get"/> 
</beans>

第四步:编写测试程序

package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.Gun;
import com.bjpowernode.spring.bean.SpringBean;
import com.bjpowernode.spring.bean.Vip;
import com.bjpowernode.spring.bean.VipFactory;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest {@Testpublic void tesInstantiation3(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Gun gun = applicationContext.getBean("gun", Gun.class);System.out.println(gun);}
}

执行结果:通过工厂方法模式也能实例化对象

4. 通过FactoryBean接口实例化

在第三种方式中,factory-bean和factory-method都是我们自己定义的。

②在Spring中,编写的类直接实现FactoryBean接口之后factory-bean和factory-method就不需要指定了!factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法!

第一步:定义一个Bean

package com.bjpowernode.spring.bean;public class Person {public Person() {System.out.println("Person的无参数构造方法执行了");}
}

第二步:编写一个类实现FactoryBean接口,重写里面的方法

PersonFactory也是一个Bean,只不过这个Bean比较特殊,叫做工厂Bean。通过工厂Bean这个特殊的Bean可以获取一个普通的Bean!

package com.bjpowernode.spring.bean;import org.springframework.beans.factory.FactoryBean;public class PersonFactory implements FactoryBean<Person> {@Overridepublic Person getObject() throws Exception {// 对象的创建也是自己new的return new Person();}@Overridepublic Class<?> getObjectType() {return null;}@Overridepublic boolean isSingleton() {// 这个方法是默认存在的,true表示单例,false表示原型return true;}
}

第三步:在Spring配置文件中配置FactoryBean

第四种:通过FactoryBean接口来实现,这种方式实际上就是第三种方式的简化!
①由于你编写的类实现了FactoryBean接口,所以这个类是一个特殊的类,不需要你再手动指定:factory-bean、factory-method。
②通过一个特殊的Bean:工厂Bean,来返回一个普通的Bean Person对象。即通过FactoryBean这个工厂Bean主要是想对普通Bean进行加工处理!

<?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"><!--Spring提供的实例化方式,第四种--><bean id="person" class="com.bjpowernode.spring.bean.PersonFactory" />
</beans>

第四步:编写测试程序

package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.*;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest {@Testpublic void tesInstantiation4(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Person person = applicationContext.getBean("person", Person.class);System.out.println(person);}
}

执行结果:通过FactoryBean接口实例化

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

5. BeanFactory和FactoryBean的区别(面试题)

(1)BeanFactory(是一个工厂)

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

(2)FactoryBean(是一个Bean)

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

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

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

6. 使用FactoryBean注入自定义Date

①前面我们说过,java.util.Date在Spring中被当做简单类型,简单类型在注入的时候可以直接使用value属性或value标签来完成。

②但是之前我们已经测试过了,对于Date类型来说,采用value属性或value标签赋值的时候,对日期字符串的格式要求非常严格,必须是这种格式的:Mon Oct 10 14:30:26 CST 2022,其他格式是不会被识别的!

③当然我们也可以当成非简单类型处理,使用ref属性来处理,但是却有一个弊端,获取的都是当前的时间,并不能自己指定时间!

注:下面我们就使用FactoryBean来完成这个骚操作!

Student类

package com.bjpowernode.spring.bean;import java.util.Date;public class Student {// 每个学生都有出生日期private Date birth;@Overridepublic String toString() {return "Student{" +"birth=" + birth +'}';}public void setBirth(Date birth) {this.birth = birth;}}

编写DateFactory实现FactoryBean接口

package com.bjpowernode.spring.bean;import org.springframework.beans.factory.FactoryBean;import java.text.SimpleDateFormat;
import java.util.Date;public class DateFactory implements FactoryBean<Date> {// 定义一个日期属性,用来处理传过来的日期字符串private String date;// 通过构造方法给日期字符串属性赋值public DateFactory(String date) {this.date = date;}@Overridepublic Date getObject() throws Exception {// 处理SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");return sdf.parse(this.date);}@Overridepublic Class<?> getObjectType() {return null;}
}

编写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"><!--通过这个类的构造方法,把字符串转换成Date--><bean id="date" class="com.bjpowernode.spring.bean.DateFactory"><constructor-arg name="date" value="1999-01-14"/></bean><!--把上面的Date通过上面的类,使用ref属性引进来--><bean id="studentBean" class="com.bjpowernode.spring.bean.Student"><property name="birth" ref="date"/></bean>
</beans>

编写测试程序

package com.bjpowernode.spring.test;import com.bjpowernode.spring.bean.*;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class BeanInstantiationTest {@Testpublic void testDate(){ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");Student studentBean = applicationContext.getBean("studentBean", Student.class);System.out.println(studentBean);}
}

执行结果

相关文章:

【Spring6】| Bean的四种获取方式(实例化)

目录 一&#xff1a;Bean的实例化方式 1. 通过构造方法实例化 2. 通过简单工厂模式实例化 3. 通过factory-bean实例化 4. 通过FactoryBean接口实例化 5. BeanFactory和FactoryBean的区别&#xff08;面试题&#xff09; 6. 使用FactoryBean注入自定义Date 一&#xff1a…...

01: 新手学SpringCloud前需知道的5点

目录 第一点&#xff1a; 什么是微服务架构 第二点&#xff1a;为什么需要学习Spring Cloud 第三点&#xff1a; Spring Cloud 是什么 第四点&#xff1a; SpringCloud的优缺点 1、SpringCloud优点 2、SpringCloud缺点 第五点&#xff1a; SpringCloud由什么组成 1&…...

ubuntu apt安装arm交叉编译工具

查找查找编译目标为32位的gcc-arm交叉编译器命令apt-cache search arm|awk index($1,"arm")!0 {print}|grep gcc-arm\|g-arm #或者 apt-cache search arm|awk index($1,"arm")!0 {print}|grep -E gcc-arm|g\\-arm输出如下g-arm-linux-gnueabihf - GNU C co…...

阿里云一面经历

文章目录 ES 查询方式都有哪些?1 基于词项的查询term & terms 查询Fuzzy QueryWildcard Query2 基于全文的查询Match QueryQuery String QueryMatch Phrase Query3 复合查询Bool QueryElasticsearch 删除原理ES 大文章怎么存arthas 常用命令arthas 排查问题过程arthas 工作…...

Java Stream中 用List集合统计 求和 最大值 最小值 平均值

对集合数据的统计&#xff0c;是开发中常用的功能&#xff0c;掌握好Java Stream提供的方法&#xff0c;避免自己写代码统计&#xff0c;可以提高工作效率。 先造点数据&#xff1a; pigs.add(new Pig(1, "猪爸爸", 31, "M", false)); pigs.add(new Pig(…...

【Linux】多线程---线程控制

进程在前面已经讲过了&#xff0c;所以这次我们来讨论一下多线程。前言&#xff1a;线程的背景进程是Linux中资源及事物管理的基本单位&#xff0c;是系统进行资源分配和调度的一个独立单位。但是实现进程间通信需要借助操作系统中专门的通信机制&#xff0c;但是只这些机制将占…...

秒杀高并发解决方案

秒杀高并发解决方案 1.秒杀/高并发方案-介绍 秒杀/高并发 其实主要解决两个问题&#xff0c;一个是并发读&#xff0c;一个是并发写并发读的核心优化理念是尽量减少用户到 DB 来"读"数据&#xff0c;或者让他们读更少的数据, 并 发写的处理原则也一样针对秒杀系统需…...

【每日一题】蓝桥杯加练 | Day07

文章目录一、三角回文数1、问题描述2、解题思路3、AC代码一、三角回文数 原题链接&#xff1a;三角回文数 1、问题描述 对于正整数 n, 如果存在正整数 k 使得n123⋯k k(k1)2\frac{k(k1)}{2}2k(k1)​ , 则 n 称为三角数。例如, 66066 是一个三角数, 因为 66066123⋯363 。 如果一…...

条件语句(分支语句)——“Python”

各位CSDN的uu们你们好呀&#xff0c;最近总是感觉特别特别忙&#xff0c;但是却又不知道到底干了些什么&#xff0c;好像啥也没有做&#xff0c;还忙得莫名其妙&#xff0c;言归正传&#xff0c;今天&#xff0c;小雅兰的内容还是Python呀&#xff0c;介绍一些顺序结构的知识点…...

论文投稿指南——中文核心期刊推荐(国家财政)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…...

面向数据安全共享的联邦学习研究综述

开放隐私计算 摘 要&#xff1a;跨部门、跨地域、跨系统间的数据共享是充分发挥分布式数据价值的有效途径&#xff0c;但是现阶段日益严峻的数据安全威胁和严格的法律法规对数据共享造成了诸多挑战。联邦学习可以联合多个用户在不传输本地数据的情况下协同训练机器学习模型&am…...

Redis经典五种数据类型底层实现原理解析

目录总纲redis的k,v键值对新的三大类型五种经典数据类型redisObject结构图示结构讲解数据类型与数据结构关系图示string数据类型三大编码格式SDS详解代码结构为什么要重新设计源码解析三大编码格式hash数据类型ziplist和hashtable编码格式ziplist详解结构剖析ziplist的优势(为什…...

Jackson 返回前端的 Response结果字段大小问题

目录 1、问题产生的背景 2、出现的现象 3、解决方案 4、成果展现 5、总结 6、参考文章 1、问题产生的背景 因为本人最近工作相关的对接外部项目&#xff0c;在我们国内有很多程序员都是使用汉语拼音或者部分字母加上英文复合体定义返回实体VO&#xff0c;这样为了能够符合…...

每天五分钟机器学习:你理解贝叶斯公式吗?

本文重点 贝叶斯算法是机器学习算法中非常经典的算法,也是非常古老的一个算法,但是它至今仍然发挥着重大的作用,本节课程及其以后的专栏将会对贝叶斯算法来做一个简单的介绍。 贝叶斯公式 贝叶斯公式是由联合概率推导而来 其中p(Y|X)称为后验概率,P(Y)称为先验概率…...

C++的入门

C的关键字 C总计63个关键字&#xff0c;C语言32个关键字 命名空间 我们C的就是建立在C语言之上&#xff0c;但是是高于C语言的&#xff0c;将C语言的不足都弥补上了&#xff0c;而命名空间就是为了弥补C语言的不足。 看一下这个例子。在C语言中会报错 #include<stdio.h>…...

数据的存储

类型的意义&#xff1a;使用这个类型开辟内存空间的大小&#xff08;大小决定了使用范围&#xff09;如何看待内存空间视角类型的基本归类整型家族浮点数家族构造类型指针类型空类型整型存储解构:整型在计算机中占用四个字节&#xff0c;整型分为无符号整型和有符号整型在计算机…...

Linux查看UTC时间

先了解一下几个时间概念。 GMT时间&#xff1a;Greenwich Mean Time&#xff0c;格林尼治平时&#xff0c;又称格林尼治平均时间或格林尼治标准时间。是指位于英国伦敦郊区的皇家格林尼治天文台的标准时间。 GMT时间存在较大误差&#xff0c;因此不再被作为标准时间使用。现在…...

SpringBoot修改启动图标(详细步骤)

目录 一、介绍 二、操作步骤 三、介绍Java学习&#xff08;题外话&#xff09; 四、关于基础知识 一、介绍 修改图标就是在资源加载目录&#xff08;resources&#xff09;下放一个banner.txt文件。这样运行加载的时候就会扫描到这个文件&#xff0c;然后启动的时候就会显…...

【每日一题Day143】面试题 17.05. 字母与数字 | 前缀和+哈希表

面试题 17.05. 字母与数字 给定一个放有字母和数字的数组&#xff0c;找到最长的子数组&#xff0c;且包含的字母和数字的个数相同。 返回该子数组&#xff0c;若存在多个最长子数组&#xff0c;返回左端点下标值最小的子数组。若不存在这样的数组&#xff0c;返回一个空数组。…...

Go 内置运算符 if for switch

算数运算符fmt.Println("103", 103) //103 13 fmt.Println("10-3", 10-3) //10-3 7 fmt.Println("10*3", 10*3) //10*3 30 //除法注意&#xff1a;如果运算的数都是整数&#xff0c;那么除后&#xff0c;去掉小数部分&#xff0c;保留整数部分 f…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

ArcPy扩展模块的使用(3)

管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如&#xff0c;可以更新、修复或替换图层数据源&#xff0c;修改图层的符号系统&#xff0c;甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...