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

株洲网站建设服务公司中国职业培训在线官方网站

株洲网站建设服务公司,中国职业培训在线官方网站,网站通栏尺寸,足球梦网站建设的基本思路解决SpringBean循环依赖为什么需要3级缓存?回答:1级Map保存单例bean。2级Map 为了保证产生循环引用问题时,每次查询早期引用对象,都拿到同一个对象。3级Map保存ObjectFactory对象。数据结构1级Map singletonObjects2级Map earlySi…

解决SpringBean循环依赖为什么需要3级缓存?

回答:1级Map保存单例bean。2级Map 为了保证产生循环引用问题时,每次查询早期引用对象,都拿到同一个对象。3级Map保存ObjectFactory对象。

数据结构

1级Map singletonObjects

2级Map earlySingletonObjects

3级Map singletonFactories

boolean allowCircularReference 是否允许循环引用

源码

DefaultSingletonBeanRegistry

    /** Cache of singleton objects: bean name to bean instance. */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** Cache of singleton factories: bean name to ObjectFactory. */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** Cache of early singleton objects: bean name to bean instance. */private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

依赖注入理解

走InstantiationAwareBeanPostProcessor.postProcessProperties最终还是调用DefaultListableBeanFactory.getBean获取bean实例进行依赖注入。

重点是从Map缓存读取实例逻辑

DefaultSingletonBeanRegistry#getSingleton

    /*** Return the (raw) singleton object registered under the given name.* <p>Checks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* @param beanName the name of the bean to look for* @param allowEarlyReference whether early references should be created or not* @return the registered singleton object, or {@code null} if none found*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lockObject singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}

AbstractAutowiredCapableBeanFactory#doCreateBean

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}}

AbstractAutowiredCapableBeanFactory#getEarlyReference

    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {Object exposedObject = bean;if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {exposedObject = bp.getEarlyBeanReference(exposedObject, beanName);}}return exposedObject;}

DefaultSingletonBeanRegistry#addSingletonFactory

    /*** Add the given singleton factory for building the specified singleton* if necessary.* <p>To be called for eager registration of singletons, e.g. to be able to* resolve circular references.* @param beanName the name of the bean* @param singletonFactory the factory for the singleton object*/protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(singletonFactory, "Singleton factory must not be null");synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}}

依赖注入的入口

调用实例化扩展点处理 InstantiationAwareBeanPostProcessor.postProcessProperties

源码

AbstractAutowiredCapableBeanFactory#populateBean

-->接口 InstantiationAwareBeanPostProcessor.postProcessProperties

----> 实现类AutowireAnnotationBeanPostProcssor.postProcessProperties

-----> metadata.inject

------> 实现类AutowriedFieldElement.inject

-------> AutowriedFieldElement.resolveFiledValue

--------> beanFactory.resolveDependency

InstantiationAwareBeanPostProcessor.postProcessProperties

    @Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//获取bean的依赖注入的元数据InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);//依赖注入metadata.inject(bean, beanName, pvs);return pvs;}

取依赖注入元数据调其inject注入

    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Collection<InjectedElement> checkedElements = this.checkedElements;Collection<InjectedElement> elementsToIterate =(checkedElements != null ? checkedElements : this.injectedElements);if (!elementsToIterate.isEmpty()) {for (InjectedElement element : elementsToIterate) {element.inject(target, beanName, pvs);}}}

AutowiredFieldElement#inject

    @Overrideprotected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;value = resolveFieldValue(field, bean, beanName);ReflectionUtils.makeAccessible(field);field.set(bean, value);}

AutowiredFiledElement#resolveFieldValue

  @Nullableprivate Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {DependencyDescriptor desc = new DependencyDescriptor(field, this.required);desc.setContainingClass(bean.getClass());Set<String> autowiredBeanNames = new LinkedHashSet<>(1);TypeConverter typeConverter = beanFactory.getTypeConverter();Object value;value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);    return value;}

DefaultListableBeanFactory#resolveDependency

  @Override@Nullablepublic Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);if (result == null) {result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);}return result;}

DefaultListableBeanFactory#doResolveDependency

@Nullablepublic Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);try {Object shortcut = descriptor.resolveShortcut(this);if (shortcut != null) {return shortcut;}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());try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());}catch (UnsupportedOperationException ex) {// A custom TypeConverter which does not support TypeDescriptor resolution...return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}} //处理多类型的bean 比如Steam 、 array、Collection、MapObject multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans != null) {return multipleBeans;}//查询依赖注入候选bean Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);//若匹配的bean为空则抛出不能找到匹配的bean异常if (matchingBeans.isEmpty()) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}return null;}String autowiredBeanName;Object instanceCandidate;// 若匹配多个候选bean,按规则(标记Primary的bean 、取PriorityOrder排序取、按字段名注入取),若都未取到抛出获取bean不唯一异常if (matchingBeans.size() > 1) {autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {return descriptor.resolveNotUnique(descriptor.getResolvableType(), 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.Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();autowiredBeanName = entry.getKey();instanceCandidate = entry.getValue();}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);}}

DefaultListableBeanFactory#findAutowireCandidates

    protected Map<String, Object> findAutowireCandidates(@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {Class<?> autowiringType = classObjectEntry.getKey();if (autowiringType.isAssignableFrom(requiredType)) {Object autowiringValue = classObjectEntry.getValue();autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);if (requiredType.isInstance(autowiringValue)) {result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);break;}}}for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {addCandidateEntry(result, candidate, descriptor, requiredType);}}if (result.isEmpty()) {boolean multiple = indicatesMultipleBeans(requiredType);// Consider fallback matches if the first pass failed to find anything...DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();for (String candidate : candidateNames) {if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&(!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {addCandidateEntry(result, candidate, descriptor, requiredType);}}if (result.isEmpty() && !multiple) {// 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;}

DefaultListableBeanFactory#addCandidateEntry

    /*** Add an entry to the candidate map: a bean instance if available or just the resolved* type, preventing early bean initialization ahead of primary candidate selection.*/private void addCandidateEntry(Map<String, Object> candidates, String candidateName,DependencyDescriptor descriptor, Class<?> requiredType) {if (descriptor instanceof MultiElementDescriptor) {Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);if (!(beanInstance instanceof NullBean)) {candidates.put(candidateName, beanInstance);}}else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&((StreamDependencyDescriptor) descriptor).isOrdered())) {Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));}else {candidates.put(candidateName, getType(candidateName));}}

DefaultListableBeanFactory#resovleCandidate

    public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)throws BeansException {return beanFactory.getBean(beanName);}
http://www.dt0577.cn/news/2344.html

相关文章:

  • 淄博政府做网站哪家好百度关键词排名突然消失了
  • 网站建设加空间百度权重5的网站能卖多少钱
  • 怎样网站制作设计站内营销推广方式
  • 网站做app的软件有哪些什么软件可以弄排名
  • 江苏廉政建设网站2022年百度seo
  • 福州网站微信公众号网络推广员有前途吗
  • 做网站设计前景怎么样东莞网络推广公司
  • 做的网站每年都要收费吗网络营销企业案例分析
  • 汕头资讯网厦门seo代理商
  • ui网上接单网站推广团队在哪里找
  • 哈尔滨网站建设nsstd上海网络推广公司网站
  • 企业网站备案信息查询系统推广方案万能模板
  • 国外网站代做百度推广价格
  • 哪家企业网站做的好百度无广告搜索引擎
  • 做网站开发平台营销推广策划方案
  • 客户做百度推广后修改网站url需要哪些流程想要网站导航正式推广
  • 网站建设合作伙伴网站网络优化外包
  • wordpress百家号windows优化大师有哪些功能
  • 推广普通话喜迎二十ppt淘宝seo排名优化软件
  • 电商网站建设小强网站优化检测工具
  • 十堰 网站建设广州seo网络推广员
  • 地方战友网站建设郑州手机网站建设
  • 做二手网站下载百度极速版
  • 深圳专业优定软件网站建设信息流优化师工作总结
  • 苏州相城做网站的厦门seo排名优化公司
  • 电商网站首页设计规范iis7站长工具
  • 地方门户网站带手机版网络平台推广运营公司
  • 惠州住房和城乡建设局网站网站营销网站营销推广
  • wordpress 获取页面url夫唯seo培训
  • 淄博做网站优化公司seo外链发布工具