疯狂的橘猫-记Spring源码-04中lambda写法的理解

本文探讨了Spring框架中使用Lambda表达式来调用createBean()方法的原理。通过一个模拟代码示例,解释了Lambda如何作为参数传递并执行,强调了在方法调用过程中,Lambda表达式先于调用方法执行,从而实现特定的功能。文章旨在帮助读者深入理解Spring框架中的Lambda用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

疯狂的橘猫-记Spring源码中lambda写法的理解

一,背景
在学习Spring获取bean对象的第二个getSingleton()方法,调用代码如下:

sharedInstance = getSingleton(beanName, () -> {
						try {
							// 创建Bean
							return AbstractBeanFactory.this.createBean(beanName, mbd, args);
						} catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							AbstractBeanFactory.this.destroySingleton(beanName);
							throw ex;
						}
					});

跟踪代码的执行流程为:
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
=》
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
好了,问题来了,为什么lambda那里,写了过后,会调用到createBean()这里??
这个之前一直没看明白,然后我看到org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata(),里面ReflectionUtils.doWithLocalFields()的写法后明白了。

  • ps 如果我写的理解有误,还请大神帮忙指正。

二,解释

通过一个代码模拟就可以看的很清楚,spring为什么要这样使用了。

public class FunctionIntf {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public FunctionIntf(String name) {
        this.name = name;
    }


    public static void getPrint(Class<? extends FunctionIntf> clazz, Target target) {
        Method[] declaredMethods = clazz.getDeclaredMethods();
        System.out.println("getPrint方法的打印" + clazz.getName());
        for (Method declaredMethod : declaredMethods) {
            target.doWith(declaredMethod);
        }
    }

    public static List<String> testPrint(String targetMethodName) {
        FunctionIntf functionIntf = new FunctionIntf("Happy");
        List<String> nameLists = new ArrayList<>();
        // getPrint(functionIntf.getClass(), met -> {},这个方法的写法解读:
        // 1.先不管lambda表达式,不管这个表达式有返回还是没有返回,都当成方法的入参
        // 2.代码执行会先执行getPrint()这个方法
        // 3.执行到getPrint()方法的 target.doWith(declaredMethod);这一句的时候
        // 就是单纯的调用传入参数的target函数式接口的实现类中的doWith()方法
        // 而这个实现的方法,就是再入参的时候定义了的。所以代码会执行到入参上面的写法
        // 总的来说,先执行调用的方法,然后按照入参时lambda定义的代码方式在执行具体的实现
        getPrint(functionIntf.getClass(), met -> {
            String name = met.getName();
            System.out.println("函数式接口获得的方法名称为:" + name);
            if (targetMethodName.equals(name)) {
                nameLists.add(name);
            }
            return null;
        });
        return nameLists;
    }

    public static void main(String[] args) {
        List<String> list = FunctionIntf.testPrint("testPrint");
        System.out.println(JSON.toJSONString(list));
    }

    @FunctionalInterface
    interface Target {
        Object doWith(Method args);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值