5、Spring源码之Supplier

问题抛出:

当别人问你 你所知道Spring中创建Bean到Spring容器的方式你知道你哪些方式嘛?


说明:

①说实话Supplier这个功能 我自己在开发中从来没有使用过、在工作中也从没见别人那么用过、但是这里为什么要说一下呢 是因为看Spring源码过程中 在实例化Bean的时候obtailFromSupplier方法不知道是干么的 所以学习了一下

②虽然开发可能不会用 但是不见得面试官不问、Spring既然提供了这样的一个方式 你可以不用,但是你要知道、当别人问的话 你可以向面试官展示一下自己技术的深度和完整度


源码跟踪:

  • 在createBeanInstance有这样一个方法 叫obtainFromSupplier 跟踪进去代码如下图所示:
    这里正常开发过程中 你所定义Bean的都是空的 , 所以正常都是无法执行obtainFromSupplier方法的

     
  • 我们思考一下 如何让这个instanceSupplier 这个对象不为空呢? 这里观察一下 是从Bean的定义信息中获取instanceSupplier对象、那我是不是可以修改Bean的定义让其不是空呢? 但是我又如何修改Bean的定义信息呢? 熟悉Spring的BeanFactoryPostProcessor知道这个类型Bean会提前加入spring的管理、 并且里面有postProcessBeanFactory方法, 能够拿到BeanFactory对象 之后修改Bean的定义信息还就很简单了嘛
     
  • 那么我们简单实现一下 代码如下:
  • 上面的代码你必须思考一下问题?上面的代码凭什么我要转为GenericBeanDefinition呢?
    ①如下图Bean定义信息的集成结构图(部分)
        

    ② 我们通过getBeanDefinition方法获取到的是一个BeanDefinition对象 通过寻找里面的方法没有能找到设置Supplier的方法
    ③那我是不是可以转成AbstractBeanDefinition呢 因为里面有setInstanceSupplier方法 这里肯定是可以的 但是还可以再精确一点嘛?
    ④这里大家要思考初始化放到容器中BeanDefinitionMap中对象是什么类型呢? 是GenericBeanDefinition类型 所有这里转成GenericBeanDefinition最精准的。但是又为什么不强转成RootBeanDefinition呢? 这时候还没合并Bean的定义信息 所以转一定会报错
     
  • obtainFromSupplier  会回调自己写的函数是接口方法 获取Bean的实例化对象

案例:

  • 配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	   xmlns:context="http://www.springframework.org/schema/context"
    	   xmlns:zhangfuyin="http://www.zhangfuyin.org/schema/zhangfuyin"
    	   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
    		http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd
    		http://www.zhangfuyin.org/schema/zhangfuyin http://www.zhangfuyin.org/schema/zhangfuyin.xsd
    ">
    
    	<bean id="supplierBean" class="com.zhangfuyin.supplier.SupplierBean"></bean>
    
    	<bean id="supplierBeanFactoryPostProcessor" class="com.zhangfuyin.supplier.SupplierBeanFactoryPostProcessor"/>
    
    
    </beans>

  • java
     
    public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		BeanDefinition beanDefinition = beanFactory.getBeanDefinition("supplierBean");
    
    		if(beanDefinition != null){
    			GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition)beanDefinition;
    			SupplierBean supplierBean = new SupplierBean();
    			genericBeanDefinition.setInstanceSupplier(supplierBean :: getSupplierBean);
    		}
    
    	}
    
    
    }
    
    =========================================================================================
    
    public class SupplierBean {
    
    
    	public SupplierBean() {
    	}
    
    	private String name;
    
    	public SupplierBean(String name) {
    		this.name = name;
    	}
    
    	public SupplierBean getSupplierBean(){
    		return new SupplierBean("supplierBean");
    	}
    
    
    }

  • 测试类
    public  static void main(String agrs[]){
    		ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:supplierBean.xml");
    
    		SupplierBean supplierBean = (SupplierBean)ac.getBean("supplierBean");
    
    		String s = (String)ac.getBean("supplierBean");
    
    		System.out.println(supplierBean);
    
    
    
    	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值