静态工厂方法和实例工厂方法注入bean实现原理

本文探讨了Spring框架中如何通过静态工厂方法和实例工厂方法进行bean注入,详细解析了配置解析过程,包括在BeanDefinitionParserDelegate.java中的处理。在bean创建时,`doCreateBean`函数用于实例化和属性注入,对于工厂方法注入,`instantiateUsingFactoryMethod`是关键。区别在于静态工厂方法不依赖于bean实例,而实例工厂方法需要通过`getBean`获取工厂bean。最后,通过反射调用相应方法完成对象创建。
摘要由CSDN通过智能技术生成

先从网上分别找两个不同实现的配置
静态工厂注入在这里插入图片描述
实例化静态工作注入在这里插入图片描述
我来先来看看spring对工厂注入配置的解析.
在文件BeanDefinitionParserDelegate.java里面parseBeanDefinitionAttributes函数里在这里插入图片描述
有这么两句话来解析xml配置,这个定义如下在这里插入图片描述
CONSTRUCTOR_ARG_ELEMENT属性获取是在另外一个函数里,大家有兴趣自己去研究.大体就是在这里数据被解析并保存.
那么在getBean的时候这些数据就派上用场了.大体流程如下图在这里插入图片描述
流程比较简单,一步一步来说下:
1.在这里插入图片描述
doCreateBean这个函数就是用来创建并进行属性注入的地方.而createBeanInstance就是bean实例化的地方.来看createBeanInstance的实现.在这里插入图片描述
2.看到高亮的没.if条件进行判断getFactoryMethodName是不是为空,实际上只要是工厂注入那么getFactoryMethodName一定不会为空.所以会走进去

3.再来看看instantiateUsingFactoryMethod的实现在这里插入图片描述
这里只是作了一个中转调用.继续跟踪
4.instantiateUsingFactoryMethod在这里插入图片描述
instantiateUsingFactoryMethod这个函数,实现体很长.在这里只截取头部.而头部也是静态工厂方法和实例工作方法最大区别的地方.
1)实例工作方法getFactoryBeanName是不为空的,所以会进入if语句块进行执行.
一.首先通过getBean方法调用生成工厂实例.factoryBean= new object();
2).静态工厂方法是没有getFactoryBeanName的,会走到else
一.静态工厂方法没有父类Bean可以依靠,所以必需有自己的class
二.factoryBean = null

instantiateUsingFactoryMethod剩余的代码两者是一样的处理过程.这个过程简单的来说如下:
1).拿到所有的工厂类的Method
2).从Method中找到配置的需要调用的method
3).从配置中拿到参数,然后进行相应的处理

最就是通过反射调用方法生成Object的过程了.我们在这里只看最后的实现,代码如下:在这里插入图片描述
这里的代码一目了然,就是使用我们找到Method,然后进行反射调用.在这里需要注意的一点就是
1.对实例工厂方法注入来说factoryBean不为空,这个反映就是一般我们常用的操作方法
2.对静态工厂来说,factoryBean= null ,这里实现上是invoke(null,args)这个用法我还没用过.不过通过实例证明是没问题的.那么我猜测其实现是判断invoke的第一个参数是不是null,如果是null就在自身的静态方法中找到对应的Method然后处理.因为静态方法不需要实例化.
最后这个实现的代码在SimpleInstantiationStrategy.java里面
在结尾贴上,我对invoke null 示例操作的结果

package com.bruk;

public class Car {

    public static void printCar(){
        System.out.println("my car");
    }
}

 Class<?> cls = Car.class;
        try {
            Method[] methd = cls.getDeclaredMethods();
            for (Method mtd : methd) {
                System.out.println(mtd.getName());
                if (mtd.getName().equals("printCar")) {
                    mtd.invoke(null,null);
                }
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

执行打印结果如下在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值