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

Spring-IOC-FactoryBean机制(难点且重点)

1、第一个案例

 1.1、Book.java

package com.atguigu.ioc;
import lombok.Data;
@Data
public class Book {private String bid;private String bname;
}

 1.2、Book2.java

package com.atguigu.ioc;
import lombok.Data;
@Data
public class Book2 extends Book {private String coffee;@Overridepublic String toString() {return "Book2{" +super.toString()+"coffee='" + coffee + '\'' +'}';}
}

1.3、applicationContext.html

<?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="p01" class="com.atguigu.ioc.Person"></bean><!--下面这个b01,IOC容器管理的是Book的实例对象,是bean的真实类型--><bean id="bo1" class="com.atguigu.ioc.Book"><property name="bid" value="boo1"/><property name="bname" value="Java从入门到放弃"/></bean><!--现在我想要Book的加强版--><!--常规情况下,IOC容器会根据class属性通过反射技术调用它的无参构造方法现在,因为class指定的类型实现了FactoryBean机制。那么IOC容器会通过反射技术调用getObject()将返回值纳入IOC--><bean id="b02" class="com.atguigu.ioc.BookFactoryBean"></bean></beans>

1.4、BookFactoryBean.java

package com.atguigu.ioc;
import org.springframework.beans.factory.FactoryBean;
public class BookFactoryBean implements FactoryBean<Book> {@Overridepublic Book getObject() throws Exception {Book2 book2 = new Book2();book2.setBid("b002");book2.setBname("钢铁是怎么炼成的");book2.setCoffee("酱香拿铁");return book2;}@Overridepublic Class<?> getObjectType() {return Book.class;}
}

1.5、Test

    @Testpublic void test11() {BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");System.out.println(beanFactory.getBean("b02"));//Book2{Book(bid=b002, bname=钢铁是怎么炼成的)coffee='酱香拿铁'}}

Spring-IOC(Inversion of Control,控制反转)是Spring框架的核心功能之一,它通过将对象的创建和依赖关系管理交给容器来实现松耦合的设计。而Spring中IOC容器提供的FactoryBean机制则是一种创建和管理Bean的途径。它允许开发者在获取Bean时,先获取一个特定的工厂Bean,然后再由工厂Bean来生成需要的最终Bean对象。

使用FactoryBean机制,主要有以下几个步骤:

1.编写自定义的FactoryBean实现类,该实现类需要实现Spring提供的 FactoryBean接口 ,重写其中的getObject()方法和getObjectType()方法。

2.在Spring容器的配置文件中,将自定义的 FactoryBean 注册 到容器中。

3.在需要使用Bean对象的地方,通过容器获取自定义的FactoryBean对象。

4.通过调用自定义FactoryBean的getObject()方法,返回需要的Bean对象。

举个例子,假设我们有一个自定义的DataSourceFactoryBean,用于创建数据源DataSource对象。那么,在Spring的配置文件中,我们可以这样配置:

<bean id="dataSource" class="com.example.DataSourceFactoryBean"/>

在程序中,如果我们需要获取DataSource对象,可以这样:

DataSourceFactoryBean dataSourceFactoryBean = (DataSourceFactoryBean) applicationContext.getBean("dataSource");
DataSource dataSource = dataSourceFactoryBean.getObject();

FactoryBean机制在一些场景中非常有用,例如:

1.在创建Bean时需要进行一些定制化操作,比如为Bean对象设置默认属性、开启/关闭某些特性等。

2.当需要实现延迟加载、缓存等特殊需求时,FactoryBean机制可以更好地实现。

总之,FactoryBean机制是Spring框架中一个非常重要的组成部分,它提供了一种更加灵活的Bean管理方式,适用于各种不同的场景。

+---------------------------------------------------------------------+
|                                Client                               |
+---------------------------------------------------------------------+|                     || 通知IOC容器加载配置文件 ||---------------------||                     |
+---------------------------------------------------------------------+
|                             IOC容器                                |
+---------------------------------------------------------------------+|                     || 创建FactoryBean实例  ||---------------------||                     || 将FactoryBean实例注册到IOC容器中 ||---------------------||                     |
+---------------------------------------------------------------------+
|                          FactoryBean                               |
+---------------------------------------------------------------------+|                     || 从配置文件中获取Bean定义 ||---------------------||                     || 创建Bean实例         ||---------------------||                     || 返回Bean实例         ||---------------------||                     |
+---------------------------------------------------------------------+
|                                Client                               |
+---------------------------------------------------------------------+|                     || 获取FactoryBean实例 ||---------------------||                     || 调用FactoryBean.getObject()方法获取Bean实例 ||---------------------||                     || 使用Bean实例         ||---------------------||                     |

在这个流程中,客户端通过IOC容器获取自定义的FactoryBean实例,然后调用其getObject()方法获取最终的Bean实例。而在IOC容器中,FactoryBean实例和最终的Bean实例都被注册到容器中,由容器统一管理和维护,使得整个过程变得更加灵活和便于扩展。

2、第二个案例

 2.1、ApplicationContext.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标签中class属性指定的是HappyFactoryBean,但是将来从这里获取的bean是HappyMachine对象--><bean id="happyMachine" class="com.atguigu.ioc.HappyFactoryBean"><!--property标签仍然可以通过setXxx()方法给属性赋值--><property name="machineName" value="iceCreamMachine"/></bean></beans>

2.2、HappyFactoryBean.java

package com.atguigu.ioc;
import org.springframework.beans.factory.FactoryBean;
//实现FactoryBean接口时需要指定泛型
//泛型类型就是当前工厂要生产的对象的类型
public class HappyFactoryBean implements FactoryBean<HappyMachine> {private String machineName;public String getMachineName() {return machineName;}public void setMachineName(String machineName) {this.machineName = machineName;}@Overridepublic HappyMachine getObject() throws Exception {//方法内部模拟创建、设置一个对象的复杂过程HappyMachine happyMachine = new HappyMachine();happyMachine.setMachineName(this.machineName);return happyMachine;}@Overridepublic Class<?> getObjectType() {//返回要生产的对象的类型return HappyMachine.class;}
}class HappyMachine {private String machineName;public String getMachineName() {return machineName;}public void setMachineName(String machineName) {this.machineName = machineName;}
}

2.3、Test

    @Testpublic void testExperiment() {ApplicationContext iocContainer = new ClassPathXmlApplicationContext("applicationContext.xml");//注意:直接根据声明FactoryBean的id,获取的是getObject方法返回的对象HappyMachine happyMachine = iocContainer.getBean("happyMachine", HappyMachine.class);System.out.println("happyMachine = " + happyMachine);//如果想要获取FactoryBean对象,直接在id前添加&符号即可!  这是一种固定的约束Object bean = iocContainer.getBean("&happyMachine");System.out.println("bean = " + bean);}//happyMachine = com.atguigu.ioc.HappyMachine@4d02f94e//bean = com.atguigu.ioc.HappyFactoryBean@2b48a640

相关文章:

  • Java面试题07
  • 重磅!TikTok Shop将以新方式重启印尼业务
  • 前端学习--React(1)
  • 小红书干货类笔记怎么写?建议收藏
  • Maven聚合项目发布至私服指定模块
  • 设计模式(二)-创建者模式(3)-抽象工厂模式
  • 使用Python解析CAN总线
  • 【华为OD题库-030】阿里巴巴找黄金宝箱(V)-java
  • 2023-浅谈模型
  • 前端面试算法之“时间复杂度
  • Qt 基于海康相机的视频绘图
  • NX二次开发UF_CAM_reinit_session 函数介绍
  • android报错
  • druid keepAlive 导致数据库连接数飙升
  • 移远通信推出六款新型天线,为物联网客户带来更丰富的产品选择
  • 深入了解以太坊
  • (ckeditor+ckfinder用法)Jquery,js获取ckeditor值
  • [ JavaScript ] 数据结构与算法 —— 链表
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • Docker入门(二) - Dockerfile
  • export和import的用法总结
  • extjs4学习之配置
  • Linux中的硬链接与软链接
  • Mac转Windows的拯救指南
  • Nacos系列:Nacos的Java SDK使用
  • win10下安装mysql5.7
  • XForms - 更强大的Form
  • Zsh 开发指南(第十四篇 文件读写)
  • 从setTimeout-setInterval看JS线程
  • 构建工具 - 收藏集 - 掘金
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 如何抓住下一波零售风口?看RPA玩转零售自动化
  • 深入 Nginx 之配置篇
  • 我这样减少了26.5M Java内存!
  • 优秀架构师必须掌握的架构思维
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​HTTP与HTTPS:网络通信的安全卫士
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (4)事件处理——(6)给.ready()回调函数传递一个参数(Passing an argument to the .ready() callback)...
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (九)c52学习之旅-定时器
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (五)Python 垃圾回收机制
  • .Net IE10 _doPostBack 未定义
  • .net wcf memory gates checking failed
  • .vue文件怎么使用_vue调试工具vue-devtools的安装
  • ::
  • :中兴通讯为何成功
  • @Controller和@RestController的区别?
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • [20160902]rm -rf的惨案.txt
  • [20190113]四校联考
  • [android] 请求码和结果码的作用