手写spring-初始化bean | 处理setter和字段的注入

54 阅读1分钟

基于廖雪峰老师的手写springboot的学习笔记

上一篇:⬅️(待补) 下一篇:➡️(待续)

在这一步中我们需要完成的是包含setter和字段的弱依赖注入。

这里的弱依赖相对于前篇提到的强依赖,强依赖是在 new bean 时就需要完成的注入,比如工厂方法创建的bean、非空参数的构造方法创建的bean;而弱依赖是允许在bean创建之后进行的注入的依赖

核心方法 callMethod

  • 如果作为参数传入的初始化方法不为空,那么我们直接调用
  • 否则当初始化方法存在时(namedMethod 不为 null ),使用 ClassUtils.getNamedMethod 方法在实际类型中找到方法,关闭访问检查后通过反射调用初始化方法。
private void callMethod(Object beanInstance, Method method, String namedMethod) {  
    // 调用init/destroy方法:  
    if (method != null) {  
        try {  
            method.invoke(beanInstance);  
        } catch (ReflectiveOperationException e) {  
            throw new BeanCreationException(e);  
        }  
    } else if (namedMethod != null) {  
        // 查找initMethod/destroyMethod="xyz",注意是在实际类型中查找:  
        Method named = ClassUtils.getNamedMethod(beanInstance.getClass(), namedMethod);  
        named.setAccessible(true);  
        try {  
            named.invoke(beanInstance);  
        } catch (ReflectiveOperationException e) {  
            throw new BeanCreationException(e);  
        }  
    }  
}

而结合 beanDefinition 的创建过程,我们其实可以清晰的判断出前者处理的是 @PostConstruct,后者处理的是工厂类的方法

BeanDefinition beanDefinition = new BeanDefinition(beanName, clazz, getSuitableConstructor(clazz),  
    getOrder(clazz), clazz.isAnnotationPresent(Primary.class),  
    null, null,  
    ClassUtils.findAnnotationMethod(clazz, PostConstruct.class),  
    ClassUtils.findAnnotationMethod(clazz, PreDestroy.class));  
addBeanDefinitions(defs, beanDefinition);

java14以上的版本支持var

var def = new BeanDefinition(ClassUtils.getBeanName(method), classType, factoryBeanName, method,  
    getOrder(method), method.isAnnotationPresent(Primary.class),  
    bean.initMethod().isEmpty() ? null : bean.initMethod(),  
    bean.destroyMethod().isEmpty() ? null : bean.destroyMethod(),  
    null, null);  
addBeanDefinitions(defs, def);

都这里了点个赞吧✨

下一篇:👉(待续)