[源码系列:手写spring] IOC第十二节:FactoryBean
内容介绍
在 Spring 框架中,FactoryBean 是一个特殊的工厂类接口,用于创建和管理复杂的 bean 对象。它允许你自定义 bean 的创建逻辑,并且可以在 bean 创建过程中执行一些额外的操作。FactoryBean 接口通常用于创建那些非常复杂或需要特殊处理的 bean 实例,例如连接池、远程服务代理等。
当我们向容器中获取FactoryBean时,容器返回的不是他本身,而是他的getObject()方法的返回值。
FactoryBean 接口有两个核心方法:
T getObject():该方法负责创建和返回一个 bean 实例。你可以在这个方法中编写自定义的 bean 创建逻辑。Class<?> getObjectType():该方法返回工厂创建的 bean 的类型。通常,它用于告诉 Spring 容器工厂创建的 bean 类型是什么。
代码分支
核心代码
FactoryBean接口
public interface FactoryBean<T> {
T getObject() throws Exception;
boolean isSingleton();
}
AbstractBeanFactory
在getBean方法中添加BeanFactory的逻辑,当bean属于BeanFactory类型的,就拿他的getObject方法返回的对象,并根据isSingleton()方法返回时决定是否加入缓存。
....
用于缓存单例的BeanFactory提供类
private final Map<String, Object> factoryBeanObjectCache = new HashMap<>();
private Object getObjectForBeanInstance(Object sharedInstance, String beanName) throws Exception {
Object obj = sharedInstance;
if(sharedInstance instanceof FactoryBean){
try {
FactoryBean factoryBean = (FactoryBean<?>)sharedInstance;
if(((FactoryBean<?>)sharedInstance).isSingleton()){
//singleton作用域bean,从缓存中获取
obj = this.factoryBeanObjectCache.get(beanName);
if( obj == null ){
obj = factoryBean.getObject();
this.factoryBeanObjectCache.put(beanName, obj);
}
}else{
//prototype作用域bean,新创建bean
obj = factoryBean.getObject();
}
}catch (Exception e){
throw new BeansException("FactoryBean threw exception on object[" + beanName + "] creation", e);
}
}
return obj;
}
....
测试
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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<bean id="person" class="bean.PersonFactoryBean">
<property name="name" value="yiHuiGoGoGO"/>
</bean>
</beans>
FactoryBean
public class PersonFactoryBean implements FactoryBean<Person> {
private String name;
@Override public Person getObject() {
Person person = new Person();
person.setName("YiHuiComeOn");
person.setAge("18");
return person;
}
@Override public boolean isSingleton() {
return true;
}
....
测试类
@Test
public void testFactoryBean(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:factory-bean.xml");
Person person = applicationContext.getBean("person", Person.class);
System.out.println(person);
}
测试结果
输出的确实是getObject返回的类,而不是类本身。
Person{name='YiHuiComeOn', age='18', car=null}
[源码系列:手写spring] IOC第十二节:FactoryBean的更多相关文章
- Spring源码分析 手写简单IOC容器
Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ...
- 《四 spring源码》手写springioc框架
手写SpringIOCXML版本 /** * 手写Spring专题 XML方式注入bean * * * */ public class ClassPathXmlApplicationContext { ...
- 框架源码系列十:Spring AOP(AOP的核心概念回顾、Spring中AOP的用法、Spring AOP 源码学习)
一.AOP的核心概念回顾 https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#a ...
- 从零开始手写 spring ioc 框架,深入学习 spring 源码
IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...
- 框架源码系列六:Spring源码学习之Spring IOC源码学习
Spring 源码学习过程: 一.搞明白IOC能做什么,是怎么做的 1. 搞明白IOC能做什么? IOC是用为用户创建.管理实例对象的.用户需要实例对象时只需要向IOC容器获取就行了,不用自己去创建 ...
- 《四 spring源码》手写springmvc
手写SpringMVC思路 1.web.xml加载 为了读取web.xml中的配置,我们用到ServletConfig这个类,它代表当前Servlet在web.xml中的配置信息.通过web.xml ...
- Spring源码 20 手写模拟源码
参考源 https://www.bilibili.com/video/BV1tR4y1F75R?spm_id_from=333.337.search-card.all.click https://ww ...
- 利用递归,反射,注解等,手写Spring Ioc和Di 底层(分分钟喷倒面试官)了解一下
再我们现在项目中Spring框架是目前各大公司必不可少的技术,而大家都知道去怎么使用Spring ,但是有很多人都不知道SpringIoc底层是如何工作的,而一个开发人员知道他的源码,底层工作原理,对 ...
- Spring源码剖析3:Spring IOC容器的加载过程
本文转自五月的仓颉 https://www.cnblogs.com/xrq730 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https ...
- 源码分析 | 手写mybait-spring核心功能(干货好文一次学会工厂bean、类代理、bean注册的使用)
作者:小傅哥 博客:https://bugstack.cn - 汇总系列原创专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言介绍 一个知识点的学习过程基本分为:运行helloworld ...
随机推荐
- ThreeJs-11精通着色器编程(重难点)
着色器语言编程比较重要,后面的几个章节都会围绕这个来做特效 一.初识着色器语言 首先什么叫做着色器,他是一种语言,首先需要设置为着色器材质,然后在材质里面书写一些语言,可以告诉他顶点,然后去自定义一些 ...
- 插入dp学习笔记
定义 插入 \(\text{dp}\) 适用于计数.求最优解且具有选择.排列元素过程等题目. 插入 \(\text{dp}\) 大致分为两类: 乱搞型:状态定义天马行空,但始终围绕着将新元素插入到旧元 ...
- mysql 使用 ibd 恢复数据
分四步: 1. 按照ibd对应的表结构,创建新表: 2. 执行: ALTER TABLE `t_健忘就多写博客` DISCARD TABLESPACE; 或者 停止mysql服务后,删除对应的 xxx ...
- HPC中常见的调度器介绍
本文分享自天翼云开发者社区<HPC中常见的调度器介绍> 作者:土豆炒肉丝 在高性能计算(HPC)环境中,调度器是负责管理和分配计算资源(如计算节点.处理器核心.内存等)给待执行任务的重要组 ...
- Javascript基础,基本数据类型,function方法,arguments对象,Error对象
Javascript基础,基本数据类型,function方法,arguments对象,Error对象1.内部脚本写在body里面好 外部脚本放在head里面引用2.基本数据类型存在堆内存中 引用类型存 ...
- nacos(二):原生java调用配置与服务实例
本文主要介绍原生java连接nacos,操作nacos的共享配置与服务实例. 1.引入依赖 <dependencies> <dependency> <groupId> ...
- JMeter非GUI模式执行,jtl文件请求与响应数据为空?这里有答案!
JMeter非GUI模式执行,jtl文件请求与响应数据为空?这里有答案! 问题描述 在使用JMeter进行性能测试时,很多用户会选择非GUI(图形用户界面)模式来执行测试,因为这样可以减少客户端的负担 ...
- Q:如何在Linux系统中查看实时网卡流量
Linux查看实时网卡流量的几种方式 来源 https://www.jianshu.com/p/b9e942f3682c 在工作中,我们经常需要查看服务器的实时网卡流量.通常,我们会通过这几种方式查 ...
- Flink基础Source配置
一.pom文件 https://www.cnblogs.com/robots2/p/16048648.html 二.代码demo FlinkBaseSource.java package net.xd ...
- CSP 考前注意事项
考试策略 J组 争取在 \(10:00\) 之前把所有题目稳定拿下.如果有题目没有思路.比较难写还没调出来或者想不出来,那么可以先放着,跳题.把其他所有题打完之后写个对拍,挂后台一直拍着. 然后剩下的 ...
https://github.com/yihuiaa/little-spring/tree/factory-bean