(七)Bean的实例化方式

news2024/11/16 5:36:27

文章目录

  • 环境
  • Bean的实例化方式
    • 通过构造方法实例化
    • 通过简单工厂模式实例化
    • 通过工厂方法模式实例化
    • 通过FactoryBean接口实例化
  • BeanFactory和FactoryBean的区别
    • BeanFactory
    • FactoryBean
  • 工厂Bean的使用:注入自定义Date

上一篇:(六)Spring之回顾工厂模式

环境

spring6里程碑版本的仓库
依赖:spring context依赖、junit依赖、log4j2依赖
log4j2.xml文件放到类路径下。

Bean的实例化方式

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

  • 第一种:通过构造方法实例化
  • 第二种:通过简单工厂模式实例化
  • 第三种:通过工厂方法模式实例化
  • 第四种:通过FactoryBean接口实例化

通过构造方法实例化

之前一直使用的就是这种方式。默认情况下,会调用Bean的无参数构造方法。
在Spring配置文件直接配置类的全路径,Spring会自动调用该类的无参数构造方法来实例化Bean。
创建一个Bean:SpringBean1类:

public class SpringBean1 {
    public SpringBean1() {
        System.out.println("Spring Bean1的无参构造方法执行");
    }
}

创建spring.xml配置:

<bean id="springBean1" class="com.bean.instantiation.bean.SpringBean1"/>

测试程序:

    @Test
    public void testInstantiation1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        SpringBean1 springBean1 = applicationContext.getBean("springBean1", SpringBean1.class);
        System.out.println(springBean1);
    }

请添加图片描述

通过简单工厂模式实例化

简单工厂模式实例化就是,创建一个简单工厂类,提供一个静态方法,手动实例化Bean对象,可见这个Bean是我们自己new出来的。
需要在Spring配置文件中告诉Spring框架,调用哪个类的哪个方法获取Bean。

定义一个Bean:SpringBean2类

public class SpringBean2 {
    public SpringBean2() {
        System.out.println("Spring Bean2的无参构造方法执行");
    }
}

定义工厂类角色:SpringBean2Factory

/**
 * 简单工厂模式中的工厂类角色。
 */
public class SpringBean2Factory {
    //简单工厂模式又叫做静态工厂方法模式,有一个静态方法。
    public static SpringBean2 get(){
        //可见这个对象最终创建的时候还是我们负责new的。
        return new SpringBean2();
    }
}

spring.xml配置:
factory-method属性:配置哪个方法获取Bean。

<bean id="springBean2" class="com.bean.instantiation.bean.SpringBean2Factory" factory-method="get"/>

测试程序:

    @Test
    public void testInstantiation2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        SpringBean2 springBean2 = applicationContext.getBean("springBean2", SpringBean2.class);
        System.out.println(springBean2);
    }

请添加图片描述

通过工厂方法模式实例化

工厂方法模式实例化就是,创建一个简单工厂类,只是这个方法不再是静态方法,而是实例方法,手动实例化Bean对象,可见这个Bean也是我们自己new出来的。
因为是实例方法,需要在Spring配置文件中配置这个工厂的Bean,并告诉Spring框架,调用哪个类的哪个方法获取Bean。

定义一个Bean:SpringBean3类

/**
 * 具体产品角色
 */
public class SpringBean3 {
    public SpringBean3() {
        System.out.println("Spring Bean3的无参构造方法执行");
    }
}

工厂角色:SpringBean3Factory类

/**
 * 具体工厂角色
 */
public class SpringBean3Factory {
    //工厂方法模式里的方法是实例方法
    public SpringBean3 get(){
        //可见,创建对象还是我们直接创建的
        return new SpringBean3();
    }
}

spring.xml配置:
通过factory-bean + factory-method共同完成
因为是实例方法,需要实例化对象,所以工厂方法也需要Spring管理,需要配置bean

  • factory-method属性:配置哪个方法获取Bean。
  • factory-bean属性:指定哪个对象创建bean
	<bean id="factory" class="com.bean.instantiation.bean.SpringBean3Factory"/>

    <bean id="springBean3" factory-bean="factory" factory-method="get"/>

测试程序:

    @Test
    public void testInstantiation3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        SpringBean3 springBean3 = applicationContext.getBean("springBean3", SpringBean3.class);
        System.out.println(springBean3);
    }

请添加图片描述

通过FactoryBean接口实例化

前三种方式中,factory-bean是我们自定义的,factory-method也是我们自己定义的。
在Spring中,当你编写的类直接实现FactoryBean接口之后,factory-bean不需要指定了,factory-method也不需要指定了。
factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。
第四种方案实际是第三种方案的简化

定义一个Bean:SpringBean4类

public class SpringBean4 {
    public SpringBean4() {
        System.out.println("Spring Bean4的无参构造方法执行");
    }
}

定义一个工厂:SpringBean4FactoryBean,实现FactoryBean接口
这个工厂也是一个Bean,只不过这个Bean比较特殊,叫做工厂Bean
通过这个工厂Bean可以获取普通的Bean
FactoryBean接口有三个方法,分别是:

  • getObject():抽象方法,在这个方法创建Bean,并返回。
  • getObjectType():抽象方法,在这个方法编写返回Bean的类型,是一个Class类型。
  • isSingleton():默认方法,它会告诉Spring,创建Bean是否是单例的,默认为true是单例的,如果不想Bean为单例,则可以覆盖此方法,并返回false就可以。
public interface FactoryBean<T> {
    String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

    @Nullable
    T getObject() throws Exception;

    @Nullable
    Class<?> getObjectType();

    default boolean isSingleton() {
        return true;
    }
}

SpringBean4FactoryBean:

public class SpringBean4FactoryBean implements FactoryBean<SpringBean4> {
    /*
       在这个方法创建Bean
     */
    @Override
    public SpringBean4 getObject() throws Exception {
        //最终也是程序员自己new的
        return new SpringBean4();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
    /*
        在源码中有一个默认方法,它会告诉Spring,创建Bean是否是单例的,如果不想单例,覆盖该方法并返回false就可以
        这里就不在操作了,默认调用接口的默认方法
     */
    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

spring.xml配置:

<bean id="springBean4" class="com.bean.instantiation.bean.SpringBean4FactoryBean"/>

测试程序:

    @Test
    public void testInstantiation4(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        SpringBean4 springBean4 = applicationContext.getBean("springBean4", SpringBean4.class);
        System.out.println(springBean4);
    }

请添加图片描述

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对象。)

工厂Bean的使用:注入自定义Date

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

所以我们可以使用FactoryBean接口对Bean的创建进行增强操作。

定义一个学生类:Student

public class Student {
    private Date birth;

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

    @Override
    public String toString() {
        return "Student{" +
                "birth=" + birth +
                '}';
    }
}

创建一个工厂Bean:DateFactoryBean类,实现FactoryBean

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;
    }
}

spring.xml配置:

	<bean id="date" class="com.bean.instantiation.bean.DateFactoryBean">
        <constructor-arg index="0" value="2020-10-11"/>
    </bean>
    <bean id="student" class="com.bean.instantiation.bean.Student">
        <property name="birth" ref="date"/>
    </bean>

测试程序:

    @Test
    public void testStudentDate(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Student student = applicationContext.getBean("student", Student.class);
        System.out.println(student);
    }

在这里插入图片描述

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

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

相关文章

【免杀前置课——Windows编程】十二、线程同步——一文讲懂什么是线程同步、原子操作函数、临界区、互斥体(激发态与非激发态区别)

线程同步线程同步多线程运行同一操作对象问题解决方案A:原子操作函数解决方案B:临界区解决方案C:互斥体激发态与非激发态互斥体优点:线程同步 多线程运行同一操作对象问题 #include<iostream> #include<Windows.h>LONG g_count 0; DWORD WINAPI myThreadProc1(_…

C语言工具——Visual Studio 的安装

很多新手朋友们&#xff0c;反应使用 IE 浏览器下载 Visual Studio 下载不下来&#xff0c;此时我们可以在 IE 浏览器上先装一个谷歌浏览器&#xff1a; https://chrom.lkcyl.cn/ . 然后打开谷歌&#xff0c;输入 VS 2019 的下载地址&#xff1a;https://learn.microsoft.com/…

深入浅出带你了解PHAR反序列化

前情提要 为了丰富自己是知识体系&#xff08;为了日更薅羊毛&#xff09;&#xff0c;我最近频繁翻阅MDN的文档&#xff0c;果然MDN文档常看常新。 最近翻到CSS部分&#xff0c;然后打开了伪类这一栏&#xff0c;好家伙&#xff0c;快60个了&#xff08;包括实验中的&#x…

【EC200U】 SIM卡使用

EC200U SIM卡SIM卡是什么SIM卡分类Quecpython SIM库调用获取sim卡的状态获取IMSI获取ICCID运行测试我们物联网要用到SIM卡&#xff0c;这张卡是4G应用的基础&#xff0c;许多功能都需要用到SIM卡。买此类板子别忘了买SIM卡哦。 SIM卡是什么 SIM卡是(Subscriber Identity Modul…

影刀连接Mysql数据库

这里写自定义目录标题官方教程下载安装Mysql-connector配置数据源填写影刀的配置的向导官方教程 官方影刀下载mysql连接教程 https://www.winrobot360.com/yddoc/language/zh-cn/%E6%8C%87%E4%BB%A4%E6%96%87%E6%A1%A3/%E5%85%B6%E4%BB%96/%E6%95%B0%E6%8D%AE%E5%BA%93/%E8%BF…

初步探索GraalVM--云原生时代JVM黑科技

1 云原生时代Java语言的困境 经过多年的演进&#xff0c;Java语言的功能和性能都在不断的发展和提高&#xff0c;诸如即时编译器、垃圾回收器等系统都能体现Java语言的优秀&#xff0c;但是想要享受这些功能带来的提升都需要一段时间的运行来达到最佳性能&#xff0c;总的来说…

linux笔记(5):按照东山派的官方教程编译buildroot(东山哪吒,D1-H)踩坑记录

文章目录1.编译流程1.1获取sdk源码1.2 补充&#xff1a;下载riscv64-glibc-gcc-thead_20200702.tar.xz1.3 补充&#xff1a;安装mtool工具1.4 安装必要依赖包1.5 编译sdcard 最小系统镜像1.6 烧录最小镜像系统到tf(SD)卡1.6.1 安装烧录工具1.6.2 格式化SD卡1.6.3 烧录镜像到sd卡…

杂篇(一)

开篇词 我本是红尘一俗客&#xff0c;没有那文人酸腐气。 曾几何时&#xff0c;梳理收藏夹&#xff0c;发现了很久前收藏的一位前端大佬的个人博客&#xff1a;怡红院落 &#xff0c;因为领域不同&#xff0c;之前一直没有拜读过他的文章。 我尚且无法判断怡红公子购买的域名…

【Log日志】springboot项目中集成Log日志详解

springboot项目中集成Log日志详解一、Log日志介绍1.Log 日志组件主要作用及用途2.日志的级别Level级别控制3.日志的输出Import3.1 快速使用3.2 日志文件输出3.3 自定义配置4. Spring Boot 日志组件 Log Plugin二、Spring Boot Logback1.依赖配置 Pom.xml2.使用 YML 配置 logbac…

Linux操作系统~系统文件IO,什么是文件描述符fd?什么是vfs虚拟文件系统

目录 1.open() &#xff08;1&#xff09;.第二个参数flags—通过比特位传多组标记 2.文件描述符fd&#xff08;open函数的返回值&#xff09; &#xff08;1&#xff09;.fd的本质 &#xff08;2&#xff09;.vfs-虚拟文件系统&#xff08;一切皆文件&#xff09; &…

MySQL Binlog 简介

MySQL Binlog Binlog 记录了所有的 DDL 和 DML(除了数据查询语句)语句&#xff0c;以事件形式记录&#xff0c;还包含语句所执行的消耗的时间&#xff0c;MySQL 的二进制日志是事务安全型的。 一般来说开启二进制日志大概会有 1%的性能损耗。 二进制日志包括两类文件&#xf…

seccon 2022 quals -simplemod

文章目录题外话调试思路如何找到对应的link_map分析do_lookup_x我的构造payloadall_exp总结题外话 这个题应该是seccon解题数量最少的了 这个题目其实和babyfile差不多&#xff0c;都是考虑0 lick,整体而言通过这两个题可以感受到出题者对于IO以及dl_resolv的理解深入 这个题目…

阻止移动端 touchmove 与 scroll 事件冲突

在移动端开发过程中&#xff0c;如果要实现一个元素或按钮的拖动定位&#xff0c;会出现很多坑。例如&#xff1a;元素上下移动过程中&#xff0c;会触发 body 的 scroll 事件&#xff0c;导致整体的位置偏移&#xff0c;这时就需要 阻止移动端 touchmove 与 scroll 事件冲突 。…

confluent-kafka-go依赖库编译体验优化

文章目录问题描述&#xff1a;解决方案1&#xff1a;编写Dockerfile文件2&#xff1a;运行Docker镜像3&#xff1a;进入镜像进行编译4&#xff1a;将编译成功的二进制文件复制到本机参考地址问题描述&#xff1a; ​ 在项目中使用了go的kafka库confluent-kafka-go&#xff0c;…

力扣(LeetCode)2. 两数相加(C++\C)

模拟 模拟加法运算&#xff0c;设置进位数 ttt &#xff0c; t(l1t(l1t(l1->vall2vall2vall2->valt)%10valt)\%10valt)%10 即为当前位上的数&#xff0c; t/10t/10t/10 即是进位数。 设置哑结点&#xff0c;便于操作头结点。 模拟上述操作&#xff0c;最后返回哑结点的…

Windows11更新最新系统版本后无法播放媒体声音

故障机器Dell为例 step1&#xff1a;检测系统提示音是否正常&#xff0c;正常可观察第二步&#xff1b; step2:打开计算机管理-设备管理器-观察声音设备是否正常&#xff0c;可右键编辑重启驱动 step3&#xff1a;打开无法播放媒体声音的设备查看设置&#xff0c;Firefox为例 …

腾讯魏巍:Eunomia云原生资源编排优化

2022年11月10日&#xff0c;在中国信通院、腾讯云、FinOps产业标准工作组联合发起的《原动力x云原生正发声 降本增效大讲堂》系列直播活动第10讲上&#xff0c;腾讯Light云计算平台负责人魏巍分享了Eunomia云原生资源编排优化实践。本文整理自魏巍的分享。 云上资源优化背景 相…

为你的服务器集成 LDAP 认证

本文内容 为什么需要 LDAP 认证如何集成 LDAP 认证Nginx 篇Apache 篇Backend 篇本文小结回顾我这些年的工作经历,面向企业(2B)和面向用户(2C)的项目都曾接触过。我个人觉得,面向企业的项目更注重业务,参与决策的人数多、周期长,目的是为企业提供生产经营价值,如缩减成本、…

kotlin coroutine源码解析之suspend挂起函数原理

目录suspend挂起函数join原理Await原理Suspend函数总结suspend挂起函数 在idea中写某些协程函数的时候&#xff0c;会有一个绿色箭头图标的出现&#xff0c;如下图&#xff1a; 而且这些方法不放在协程里面写的话&#xff0c;idea编辑器还会报错&#xff0c;如下图&#xff1…

基于python的人力资源管理系统

摘 要 随着当今社会的发展&#xff0c;时代的进步&#xff0c;各行各业也在发生着变化&#xff0c;比如人力资源管理这一方面&#xff0c;利用网络已经逐步进入人们的生活。传统的人力资源管理&#xff0c;都是员工去公司查看部门信息、招聘信息&#xff0c;这种传统方式局限性…