当前位置: 首页 > news >正文

spring源码(bean的实例化)——determineCandidateConstructors篇

引言

        determineCandidateConstructors——spring创建实例无法避免的一个方法,大家一起学习,让我们对spring创建bean的过程更加深刻

代码

    @Nullable
    public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
//在开始处理构造函数之前,先检查beanClass中是否存在@Lookup注解的方法。如果有,可能会影响构造函数的选择。
        this.checkLookupMethods(beanClass, beanName);
//首先尝试从缓存candidateConstructorsCache中获取该beanClass的候选构造函数。
//如果缓存中不存在,则进入同步块进一步处理。
        Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
        if (candidateConstructors == null) {
//使用同步块确保线程安全,避免多个线程同时处理同一个beanClass的构造函数。
            synchronized(this.candidateConstructorsCache) {
                candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
                if (candidateConstructors == null) {
                    Constructor<?>[] rawCandidates;
                    try {
//通过反射获取beanClass中所有声明的构造函数
                        rawCandidates = beanClass.getDeclaredConstructors();
                    } catch (Throwable ex) {
                        throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + String.valueOf(beanClass.getClassLoader()) + "] failed", ex);
                    }
/**
初始化变量:
candidates: 存储候选构造函数的列表。
requiredConstructor: 标记带有@Autowired(required=true)注解的构造函数。
defaultConstructor: 标记无参构造函数。
primaryConstructor: 通过BeanUtils.findPrimaryConstructor找到的主构造函数。
nonSyntheticConstructors: 统计非合成构造函数的数量。**/

                    List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
                    Constructor<?> requiredConstructor = null;
                    Constructor<?> defaultConstructor = null;
                    Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
                    int nonSyntheticConstructors = 0;

/**
过滤合成构造函数: 合成构造函数(如内部类的构造函数)通常不需要处理。
查找@Autowired注解: 通过findAutowiredAnnotation方法检查构造函数是否带有@Autowired注解。
处理无参构造函数: 如果构造函数没有参数,则标记为defaultConstructor。**/
                    for(Constructor<?> candidate : rawCandidates) {
                        if (!candidate.isSynthetic()) {
                            ++nonSyntheticConstructors;
                        } else if (primaryConstructor != null) {
                            continue;
                        }

                        MergedAnnotation<?> ann = this.findAutowiredAnnotation(candidate);
                        if (ann == null) {
                            Class<?> userClass = ClassUtils.getUserClass(beanClass);
                            if (userClass != beanClass) {
                                try {
                                    Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
                                    ann = this.findAutowiredAnnotation(superCtor);
                                } catch (NoSuchMethodException var19) {
                                }
                            }
                        }

                        if (ann != null) {
                            if (requiredConstructor != null) {
                                String var23 = String.valueOf(candidate);
                                throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + var23 + ". Found constructor with 'required' Autowired annotation already: " + String.valueOf(requiredConstructor));
                            }

                            boolean required = this.determineRequiredStatus(ann);
                            if (required) {
                                if (!candidates.isEmpty()) {
                                    String var10003 = String.valueOf(candidates);
                                    throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + var10003 + ". Found constructor with 'required' Autowired annotation: " + String.valueOf(candidate));
                                }

                                requiredConstructor = candidate;
                            }

                            candidates.add(candidate);
                        } else if (candidate.getParameterCount() == 0) {
                            defaultConstructor = candidate;
                        }
                    }

/**优先选择带有@Autowired注解的构造函数。
如果没有合适的构造函数,则根据以下规则选择:
如果只有一个构造函数且带参数,则选择该构造函数。
如果有两个非合成构造函数(主构造函数和无参构造函数),则选择它们。
如果只有一个非合成构造函数(主构造函数),则选择它。
否则,返回空数组。**/
                    if (!candidates.isEmpty()) {
                        if (requiredConstructor == null) {
                            if (defaultConstructor != null) {
                                candidates.add(defaultConstructor);
                            } else if (candidates.size() == 1 && this.logger.isInfoEnabled()) {
                                this.logger.info("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor is effectively required since there is no default constructor to fall back to: " + String.valueOf(candidates.get(0)));
                            }
                        }

                        candidateConstructors = (Constructor[])candidates.toArray(EMPTY_CONSTRUCTOR_ARRAY);
                    } else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
                        candidateConstructors = new Constructor[]{rawCandidates[0]};
                    } else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
                        candidateConstructors = new Constructor[]{primaryConstructor, defaultConstructor};
                    } else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
                        candidateConstructors = new Constructor[]{primaryConstructor};
                    } else {
                        candidateConstructors = EMPTY_CONSTRUCTOR_ARRAY;
                    }
//将最终确定的候选构造函数存入缓存,避免重复计算。
                    this.candidateConstructorsCache.put(beanClass, candidateConstructors);
                }
            }
        }

        return candidateConstructors.length > 0 ? candidateConstructors : null;
    }

 讲解

        总的来说就是根据你创建的bean,判断是否为有参构造,是否为无参构造,是否通过Autowired进行了注解,这是我的理解,大佬们也可以多多补充一下,因为这也是我在背八股文时一直背不到这个才请教大佬,大佬叫我看源码我理解的

但是还是不怎么理解,只是把这个方法能够理解表层了

相关文章:

  • Mac 上自动安装DeepSeek-R1 1.5B
  • DEFI币生态重构加速,XBIT去中心化交易所引领DEX安全新范式
  • springboot操作redis集群,注意事项
  • 如何写一个网关的系统
  • 网络安全漏洞的种类分为哪些?
  • chrome.webRequest API 和 Performance API
  • Java多线程与高并发专题——ThreadLocal 适合用在哪些实际生产的场景中?
  • JavaScript 导出功能全解析:从数据到文件
  • 算法刷题记录——专题目录汇总
  • 【css酷炫效果】纯CSS实现球形阴影效果
  • 【Linux笔记】动态库与静态库的制作
  • windows安装配置FFmpeg教程
  • 数字化工厂智能制造精益化管理智能工厂数据分析大数据解决方案精品PPT格式
  • Kafka-ConsumerRecord
  • SpringBoot前后端不分离,前端如何解析后端返回html所携带的参数
  • linux系统正常,浏览器却无法访问网页
  • 【PyTorch】y = x.flatten(2).permute(0, 2, 1)
  • GGUF量化模型技术解析与DeepSeek-R1-Distill-Llama-8B选型指南
  • VMware-workstation-17.6.3安装教程
  • 涨薪技术|Kubernetes(k8s)之认识Pod
  • 做关键词排名卖网站/深圳网站关键词
  • 做个人网站要多少钱/网络安全有名的培训学校
  • 模板网站建设价位/百度小说排行榜总榜
  • 公司简介范本/东营seo网站推广
  • 做旅行路线的网站/2345浏览器主页网址
  • 买衣服的网站排行榜/竞价排名服务