Spring自动注入的应用
发表于:2025-02-05 作者:千家信息网编辑
千家信息网最后更新 2025年02月05日,这篇文章主要讲解了"Spring自动注入的应用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring自动注入的应用"吧!自动装配@Nullable
千家信息网最后更新 2025年02月05日Spring自动注入的应用
这篇文章主要讲解了"Spring自动注入的应用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Spring自动注入的应用"吧!
自动装配
@Nullablepublic Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable SetautowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException { InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor); try { Object shortcut = descriptor.resolveShortcut(this); if (shortcut != null) { return shortcut; } // class com.ypf.ServiceB Class> type = descriptor.getDependencyType(); Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter); if (multipleBeans != null) { return multipleBeans; } // 关键点 !!! 去 spring ioc 容器中找到需要注入的 type 类型的 bean Map matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } return null; } String autowiredBeanName; Object instanceCandidate; if (matchingBeans.size() > 1) { // Determine the autowire candidate in the given set of beans. // Looks for {@code @Primary} and {@code @Priority} (in that order). autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (autowiredBeanName == null) { if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { return descriptor.resolveNotUnique(type, matchingBeans); } else { // In case of an optional Collection/Map, silently ignore a non-unique case: // possibly it was meant to be an empty collection of multiple regular beans // (before 4.3 in particular when we didn't even look for collection beans). return null; } } instanceCandidate = matchingBeans.get(autowiredBeanName); } else { // We have exactly one match. // 将得到的 bean 从 matchingBeans 这个 map 中取出来。 Map.Entry entry = matchingBeans.entrySet().iterator().next(); autowiredBeanName = entry.getKey(); instanceCandidate = entry.getValue(); } // 为什么要加入 成功注入 beanName 放到一个 Set 集合中 if (autowiredBeanNames != null) { autowiredBeanNames.add(autowiredBeanName); } // ??? if (instanceCandidate instanceof Class) { instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this); } Object result = instanceCandidate; if (result instanceof NullBean) { if (isRequired(descriptor)) { raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor); } result = null; } if (!ClassUtils.isAssignableValue(type, result)) { throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass()); } return result; } finally { ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint); } }
DependencyDescriptor
依赖描述器,大概描述了 XXX 里的 field 需要自动装配 xxx 类型的 bean。
descriptor.resolveCandidate 里面实际上就是调用了 getBean
findAutowireCandidates
根据一些规则找到一些 candidateNames,把这些 candidateName,beanInstance 放到 map 中返回。 beanInstance 是根据调用 getBean(candidateName) 得到的。
protected MapfindAutowireCandidates( @Nullable String beanName, Class> requiredType, DependencyDescriptor descriptor) { // 先根据自动装配的 Class 类型去找到 spring ioc 容器中的所有是这种类型的 bean 的 name。 // Ancestors 祖先 String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this, requiredType, true, descriptor.isEager()); Map result = new LinkedHashMap<>(candidateNames.length); // 解析过的依赖会被缓存起来,根据 requiredType 去看缓存中没有有,有的话直接取出来 for (Class> autowiringType : this.resolvableDependencies.keySet()) { if (autowiringType.isAssignableFrom(requiredType)) { Object autowiringValue = this.resolvableDependencies.get(autowiringType); autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType); if (requiredType.isInstance(autowiringValue)) { result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue); break; } } } for (String candidate : candidateNames) { // 如果自动装配的属性的类型不是这个类,且是自动装配的候选就加入到 result。按 byType if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty() && !indicatesMultipleBeans(requiredType)) { // Consider fallback matches if the first pass failed to find anything... DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch(); for (String candidate : candidateNames) { // 如果自动装配的属性的类型不是这个类,且是自动装配的候选就加入到 result。按 byName 去找。 if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } if (result.isEmpty()) { // Consider self references as a final pass... // but in the case of a dependency collection, not the very same bean itself. for (String candidate : candidateNames) { if (isSelfReference(beanName, candidate) && (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) && isAutowireCandidate(candidate, fallbackDescriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } } } return result; }
???
isAutowireCandidate
先按 byType 去找,然后去按 byName 去找?
protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) throws NoSuchBeanDefinitionException { String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName); if (containsBeanDefinition(beanDefinitionName)) { return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver); } else if (containsSingleton(beanName)) { return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver); } BeanFactory parent = getParentBeanFactory(); if (parent instanceof DefaultListableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((DefaultListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor, resolver); } else if (parent instanceof ConfigurableListableBeanFactory) { // If no DefaultListableBeanFactory, can't pass the resolver along. return ((ConfigurableListableBeanFactory) parent).isAutowireCandidate(beanName, descriptor); } else { return true; }}
感谢各位的阅读,以上就是"Spring自动注入的应用"的内容了,经过本文的学习后,相信大家对Spring自动注入的应用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!
装配
类型
应用
学习
内容
容器
就是
属性
缓存
成功
关键
关键点
实际
实际上
思路
情况
文章
更多
知识
知识点
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
常用空间数据库简介
数据库原理视频知识
云服务器可以恢复出厂设置吗
数据库保障安全吗
app是如何去访问服务器的
剑灵答题软件开发
服务器备份制度
俄网络安全
江河创建集团软件开发
vba表格录入数据库代码
学习网络安全法活动结束语
公安负责网络安全
黑龙江省软件开发公司
服务器版pe工具
ppp服务器中断了您的链接
郭建华网络安全
互联网科技最新资讯
云南服务器推送云空间
帝国ol是用什么软件开发的
王者号怎样查询登录过的服务器
局域网服务器能设几个ip
全国网络安全大赛答题入口
家庭网络技术的功能
湖畔网络技术有限公司待遇
无锡新品服务器供货厂
同城的软件开发
金融科技为互联网金融服务
戴尔网络安全设备
石嘴山网络安全意识形态责任制
昌吉云服务器服务保障