spring循环依赖debug源码【Java面试第三季】

news2025/1/18 7:48:50

spring循环依赖debug源码【Java面试第三季】

  • 前言
  • spring循环依赖debug源码
  • 35_spring循环依赖debug源码01
        • 全部Debug断点
  • 36_spring循环依赖debug源码02
  • 37_spring循环依赖debug源码03
  • 38_spring循环依赖debug源码04
  • 最后

前言

本文是4.Spring【Java面试第三季】的小节

spring循环依赖debug源码

35_spring循环依赖debug源码01

全部Debug断点

DEBUG一步一步来,scope默认为singleton

从运行类启航

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ClientSpringContainer {

	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//此处断点
		A a = context.getBean("a", A.class);
		B b = context.getBean("b", B.class);
	}

}

步入步出

再步入

    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
        this(new String[]{configLocation}, true, (ApplicationContext)null);//到这行
    }

再步入

    public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
        super(parent);//到这行
        this.setConfigLocations(configLocations);
        if (refresh) {
            this.refresh();//步进到这 spring容器初始化 该行打断点 
        }

    }

全部跳过就会运行结束

重新开始调试,跳过该断点

到这步了

package org.springframework.context.support;

...

public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
    
    public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}
    
	public ClassPathXmlApplicationContext(
			String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
            //源于AbstractXmlApplicationContext
            //->AbstractRefreshableConfigApplicationContext
            //->AbstractRefreshableApplicationContext
            //->AbstractApplicationContext的refresh()
			refresh();
		}
	}
    
}

步入refresh方法
一步一步步过直到控制台打印到A B创建对象
最终,在这行this.finishBeanFactoryInitialization(beanFactory);打了断点

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);//所以在此处打断点
                this.finishRefresh();//直到此处会打印结果,所以在此处上一行打断点
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

再次debug

package org.springframework.context.support;

...

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    
    ...
        
    @Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

--------------->//<---------------------重点关注点是这里
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
    

进入到第三处断点 this.finishBeanFactoryInitialization(beanFactory);

/**
	 * Finish the initialization of this context's bean factory,
	 * initializing all remaining singleton beans.
	 */
	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();

------->//<---------------------重点关注点是这里
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();//第4处断点
	}
    
}

36_spring循环依赖debug源码02

接着上文的beanFactory.preInstantiateSingletons()

beanFactory是ConfigurableListableBeanFactory

DefaultListableBeanFactory实现了ConfigurableListableBeanFactory接口

再次debug到第四个断点beanFactory.preInstantiateSingletons();

进入该行

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    ...
    
    @Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) { //到这行
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
		//根据上下文beanNames为[a, b] size=2
        
		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {//遍历a,b
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
------------------->//<---------------------重点关注点是这里
    				//源于AbstractAutowireCapableBeanFactory
    				//->AbstractBeanFactory的getBean()
					getBean(beanName);  //第5处断点就是这
				}
			}
		}

------------------------------下面可略读---------------------------
		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}    
    
}

进入第5处断点getBean(beanName);

doXXX真正干实事的业务逻辑方法

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//到该行  再次进入
	}
protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);//到该行
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//该行打断点 进入
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

进入Object sharedInstance = getSingleton(beanName);//该行打断点 进入

	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);//再进入 
	}
	
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);//到该行	再次打断点  singletonObject=null 此时还没有A的对象
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;//返回null
	}

返回null到getSingleton()
再次返回null到Object sharedInstance = getSingleton(beanName);

package org.springframework.beans.factory.support;

...

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
	...
    @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
    
    
	@SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

        //name为a
		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
------->//<---------------------重点关注点是这里
------->//<---------------------重点关注点是这里
------->//<---------------------重点关注点是这里
    	//源于FactoryBeanRegistrySupport
    	//->DefaultSingletonBeanRegistry的getSingleton()
    	//DefaultSingletonBeanRegistry也就是上文谈论的三级缓存所在类
    	//本章节末有getSingleton()源码
    	//最后getSingleton返回null
		Object sharedInstance = getSingleton(beanName);
        //sharedInstance为null,下面if语块不执行
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
            //不执行下面if语块
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
            //parentBeanFactory为null,不执行下面if语块
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);//标记A对象
			}

			try {
				//下面方法返回Root bean: class [com.lun.interview.circular.A]; 
                //scope=singleton; abstract=false; lazyInit=false; 
                //autowireMode=0; dependencyCheck=0; autowireCandidate=true; 
                //primary=false; factoryBeanName=null; factoryMethodName=null; 
                //initMethodName=null; destroyMethodName=null; 
                //defined in class path resource [beans.xml]
                //重点关注scope=singleton
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
                //dependsOn返回null,不执行下面if语块
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance.
                //mbd.isSingleton()返回true,执行下面if语块
				if (mbd.isSingleton()) {//重点来了
					sharedInstance = getSingleton(beanName, () -> {  //断点此处 进入 看下节
						try {
--------------------------->//<---------------------重点关注点是这里
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

----------------------------下面代码可略读---------
    ------------------
                
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					if (!StringUtils.hasLength(scopeName)) {
						throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
					}
					Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				if (logger.isTraceEnabled()) {
					logger.trace("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}
}

37_spring循环依赖debug源码03

进入sharedInstance = getSingleton(beanName, () -> { //断点此处 进入 看下节

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");//到此处
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();//此行打断点 再次进入
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}


进入singletonObject = singletonFactory.getObject();//此行打断点 再次进入

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

进入return createBean(beanName, mbd, args);//到此处 打断点

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isTraceEnabled()) {//到此处
			logger.trace("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

		// Make sure bean class is actually resolved at this point, and
		// clone the bean definition in case of a dynamically resolved Class
		// which cannot be stored in the shared merged bean definition.
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);//此处打断点 进入
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			// A previously detected exception with proper bean creation context already,
			// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

进入Object beanInstance = doCreateBean(beanName, mbdToUse, args);//此处打断点 进入

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;//到此处
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);// 创建Bean的实例 打断点进入
		}
		...
	}

进入instanceWrapper = createBeanInstance(beanName, mbd, args);// 创建Bean的实例 打断点进入

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		...//无关键
	}

出去到instanceWrapper = createBeanInstance(beanName, mbd, args);

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);//出来到这
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 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)); //到此处 A是否是单例 是否允许循环引用(true) 
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//此处打断点 进入
		}

		...
	}

进入addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//此处打断点 进入

	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {//一级缓存有无A
				this.singletonFactories.put(beanName, singletonFactory);//存入三级缓存 a 拉姆达表达式
				this.earlySingletonObjects.remove(beanName);//二级缓存删除A
				this.registeredSingletons.add(beanName);//注册bean
			}
	

退出到addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//此处打断点 进入


protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
			
			....
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//退出
		}

		// Initialize the bean instance.
		Object exposedObject = bean;//到此处
		try {
			populateBean(beanName, mbd, instanceWrapper);//此处打断点 进入
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		...

此时A在三级缓存中

进入populateBean(beanName, mbd, instanceWrapper);//此处打断点 进入

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (bw == null) {//到该行
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			else {
				// Skip property population phase for null instance.
				return;
			}
		}

		// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
		// state of the bean before properties are set. This can be used, for example,
		// to support styles of field injection.
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
						return;
					}
				}
			}
		}

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//pvs: "PropertyValues: length=i; bean property 'b'"  A有一个属性B

		//中间略过
		
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);//进入此处
		}
	}

进入applyPropertyValues(beanName, mbd, bw, pvs);//进入此处

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		if (pvs.isEmpty()) {//到此处
			return;
		}

		if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
			((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
		}

		MutablePropertyValues mpvs = null;
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			original = mpvs.getPropertyValueList(); //A中要有属性B
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// Create a deep copy, resolving any references for values.
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				String propertyName = pv.getName();//propertyName="b"
				Object originalValue = pv.getValue();
				if (originalValue == AutowiredPropertyMarker.INSTANCE) {
					Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
					if (writeMethod == null) {
						throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
					}
					originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
				}
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//此处打断点 进入
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
				}
				// Possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}


进入Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//此处打断点 进入

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {//到此处 要对B下手了
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//打断点 进入
		}
		...
	}

进入return resolveReference(argName, ref);

@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		try {
			Object bean;
			Class<?> beanType = ref.getBeanType();//到此处
			if (ref.isToParent()) {
				BeanFactory parent = this.beanFactory.getParentBeanFactory();
				if (parent == null) {
					throw new BeanCreationException(
							this.beanDefinition.getResourceDescription(), this.beanName,
							"Cannot resolve reference to bean " + ref +
									" in parent factory: no parent factory available");
				}
				if (beanType != null) {
					bean = parent.getBean(beanType);
				}
				else {
					bean = parent.getBean(String.valueOf(doEvaluate(ref.getBeanName())));
				}
			}
			else {
				String resolvedName;
				if (beanType != null) {
					NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
					bean = namedBean.getBeanInstance();
					resolvedName = namedBean.getBeanName();
				}
				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);//到此处 打断点  控制台打印了---A created success
				}
				this.beanFactory.registerDependentBean(resolvedName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					this.beanDefinition.getResourceDescription(), this.beanName,
					"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
		}
	}

进入bean = this.beanFactory.getBean(resolvedName);//到此处 打断点 控制台打印了---A created success

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//再进去
	}
protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//再进入
		
}
	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);//再进入
	}
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;//返回null 因为B还没有
	}

返回返回到if (sharedInstance != null && args == null) {//退出到此处

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {//退出到此处
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		//快速到此处
		
				// Create bean instance.
				if (mbd.isSingleton()) { 
					sharedInstance = getSingleton(beanName, () -> { //断点 此时是创建B 进入 
						try {
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				....

进入sharedInstance = getSingleton(beanName, () -> { //断点 此时是创建B 进入

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
			Object singletonObject = this.singletonObjects.get(beanName);//一级缓存没有B
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
					singletonObject = singletonFactory.getObject();//容器中没有B,到此处  进入
					newSingleton = true;
				}
			...
			return singletonObject;
		}
	}

回调到return createBean(beanName, mbd, args);

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		...
	
		
				// Create bean instance.
				if (mbd.isSingleton()) { 
					sharedInstance = getSingleton(beanName, () -> { 
						try {
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				....

进入return createBean(beanName, mbd, args);//回调到此处 断点 进入

	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

	   //快速跳过
		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);//到此处 现在建的是B 再进入
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		...
	}

进入Object beanInstance = doCreateBean(beanName, mbdToUse, args);//到此处 现在建的是B 再进入

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);//建B 再进入
		}
		...
		return exposedObject;
	}

进入instanceWrapper = createBeanInstance(beanName, mbd, args);//建B 再进入

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		...
		
		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd); //完成B的初始化
	}


返回instanceWrapper = createBeanInstance(beanName, mbd, args);

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);//返回
		}
		
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, 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));//到此处断点 建B
		}

		...

		return exposedObject;
	}


再次进入addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//到此处断点 建B

	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");//到此处
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {//一级缓存有B 无 !无=true
				this.singletonFactories.put(beanName, singletonFactory);//三级缓存存入B 拉姆达
				this.earlySingletonObjects.remove(beanName);//清理二级缓存
				this.registeredSingletons.add(beanName);//填充注册
			}
		}
	}

三级缓存中有B

返回addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));//返回
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);//属性填充B 进入
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

进入populateBean(beanName, mbd, instanceWrapper);//属性填充B 进入

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
	    ...

		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//B里面有一个属性A
		
		...
		
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);//此处打断点 进入
		}
	}


进入applyPropertyValues(beanName, mbd, bw, pvs);//此处打断点 进入

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		
		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(), beanName, "Error setting property values", ex);
				}
			}
			original = mpvs.getPropertyValueList();//B中有属性A
		}
		

		//快速跳到断点
		
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//断点  进入
				...
	}

进入Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//断点 进入

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//再次进入
		}

进入return resolveReference(argName, ref);//再次进入

@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {
		
		....
			else {
				String resolvedName;
				if (beanType != null) {
					NamedBeanHolder<?> namedBean = this.beanFactory.resolveNamedBean(beanType);
					bean = namedBean.getBeanInstance();
					resolvedName = namedBean.getBeanName();
				}
				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);//到此断点 进入
				}
				this.beanFactory.registerDependentBean(resolvedName, this.beanName);
			}

进入bean = this.beanFactory.getBean(resolvedName);//到此断点 进入

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//进入
	}

进入return doGetBean(name, null, null, false);//进入

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//进入
	}

进入return doGetBean(name, null, null, false);//进入

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//进入
		...
	}

进入Object sharedInstance = getSingleton(beanName);//进入

	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);//进入
	}

进入return getSingleton(beanName, true);

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//一级缓存没有A
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存没有A
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);//三级缓存中有A
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();//打断点 进入
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

进入singletonObject = singletonFactory.getObject();//打断点 进入

		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  //value 拉姆达

进入addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); //value 拉姆达

	protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
		Object exposedObject = bean;//到此处
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				}
			}
		}
		return exposedObject;//返回了A对象
	}

返回到singletonObject = singletonFactory.getObject();

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//一级缓存没有A
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存没有A
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);//三级缓存中有A
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();//返回
						this.earlySingletonObjects.put(beanName, singletonObject);//二级缓存处内A A对象
						this.singletonFactories.remove(beanName);//三级缓存中移除A
					}
				}
			}
		}
		return singletonObject;//返回A(属性B=null)
	}

二级缓存中存入A 和A对象 (B属性是null)(通过三级缓存value () -> getEarlyBeanReference(beanName, mbd, bean)创建的)

三级缓存中删掉A

返回

	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);
	}

返回Object sharedInstance = getSingleton(beanName);

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//返回	A对象(属性B=null)
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);//下一步
		}
		...

		
		return (T) bean;//返回对象A(属性B=null)
	}

再返回

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}
	@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {
	
				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));//返回
					bean = this.beanFactory.getBean(resolvedName);//
				}
				this.beanFactory.registerDependentBean(resolvedName, this.beanName);//注册依赖的Bean
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;//返回A(属性B=null)
		}
		
	}

返回

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//返回
		}

返回到

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//返回
				Object convertedValue = resolvedValue;
				

		// Set our (possibly massaged) deep copy.
		try {
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));//完成了B属性的填充
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}

返回到B属性的填充

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

返回到创建B

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {


		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);//返回
			exposedObject = initializeBean(beanName, exposedObject, mbd);//到这 进入
		}
	
		return exposedObject;
	}

进入exposedObject = initializeBean(beanName, exposedObject, mbd);//到这 进入

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		//B填充了A(属性B=null)
		return wrappedBean;//返回B(属性A=a(属性B=null))
	}

返回doCreateBean

  		...
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);//打断点 进去
		

进入Object earlySingletonReference = getSingleton(beanName, false);//打断点 进去

	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {//一级缓存没有B
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存没有B
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;//返回null
	}

返回到doGetBean

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);//返回null




		return exposedObject;//返回B(A=a(B=null))
	}

返回到createBean

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);//返回B(A=a(B=null))
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;//返回B(A=a(B=null))
		}

	}

返回到doGetBean

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);//返回B(A=a(B=null))
						}

返回到getSingleton

				try {
					singletonObject = singletonFactory.getObject();//返回了B(A=a(B=null))
					newSingleton = true;
				}
				
				if (newSingleton) {
					addSingleton(beanName, singletonObject);//到此处 打断点 进入
				}

进入addSingleton(beanName, singletonObject);//到此处 打断点 进入

	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);//一级缓存存入B b(A=a(B=null))
			this.singletonFactories.remove(beanName);//三级缓存删除B
			this.earlySingletonObjects.remove(beanName);//二级缓存删除B
			this.registeredSingletons.add(beanName);//注册完成
		}
	}

B是直接从三级缓存到一级缓存了

返回到getSingleton

		return singletonObject;//返回b(A=a(B=null))

返回到doGetBean

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {//返回
						try {
							return 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.
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				...
				return (T) bean;//返回b(A=a(B=null))

返回

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//返回b(A=a(B=null))
	}

返回到resolveReference

				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);//返回
				}
				this.beanFactory.registerDependentBean(resolvedName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;//返回b(A=a(B=null))
		}

返回

	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//返回 b(A=a(B=null))
		}

返回

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
				...
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//返回了b(A=a(B=null))
				Object convertedValue = resolvedValue;
				//退出
	}

返回到populateBean A的属性填充

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);//再次进入
		}
	}
	
	

进入applyPropertyValues(beanName, mbd, bw, pvs);//再次进入

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
	
			original = mpvs.getPropertyValueList();//A的属性B需要填充
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

	
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//再进去
				

进入Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//再进去

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//进入
		}
		

进入return resolveReference(argName, ref);//进入

@Nullable
	private Object resolveReference(Object argName, RuntimeBeanReference ref) {

				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);//到此断点 进入
				}
			
		
	}

进入bean = this.beanFactory.getBean(resolvedName);//到此断点 进入

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);//在进入
	}

进入

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//进入
		

进入

	@Override
	@Nullable
	public Object getSingleton(String beanName) {
		return getSingleton(beanName, true);//再进入
	}


	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		Object singletonObject = this.singletonObjects.get(beanName);//一级缓存有B
	
		return singletonObject;//返回b(A=a(B=null))
	}

返回b(A=a(B=null))到return getSingleton(beanName, true);

返回到doGetBean

		Object sharedInstance = getSingleton(beanName);//返回了b(A=a(B=null))
		...
		return (T) bean;//返回b(A=a(B=null))
	}

返回到resolveReference

				else {
					resolvedName = String.valueOf(doEvaluate(ref.getBeanName()));
					bean = this.beanFactory.getBean(resolvedName);//返回了b(A=a(B=null))
				}
				this.beanFactory.registerDependentBean(resolvedName, this.beanName);
			}
			if (bean instanceof NullBean) {
				bean = null;
			}
			return bean;//返回b(A=a(B=null))
		}

返回return resolveReference(argName, ref);

	@Nullable
	public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
		// We must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);//返回b(A=a(B=null))
		}
		

退出Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);

	protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
				...
				
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);//返回了b(A=a(B=null))
				Object convertedValue = resolvedValue;
				
				//退出
	}

返回doCreateBean


	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
			
		...
		try {
			populateBean(beanName, mbd, instanceWrapper);//退出
			exposedObject = initializeBean(beanName, exposedObject, mbd);//进入
		}
		

进入exposedObject = initializeBean(beanName, exposedObject, mbd);//进入

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {

		Object wrappedBean = bean;//对A进行处理
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}


		return wrappedBean;//返回
	}

退出exposedObject = initializeBean(beanName, exposedObject, mbd);到doCreateBean

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);//退出
		}
		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);//进入


进入Object earlySingletonReference = getSingleton(beanName, false);//进入

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {//a false
		Object singletonObject = this.singletonObjects.get(beanName);//一级缓存不存在A
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
				singletonObject = this.earlySingletonObjects.get(beanName);//二级缓存中有A
				if (singletonObject == null && allowEarlyReference) {
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;//返回了二级缓存中的A
	}

返回到doCreateBean

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);//返回了A
			
			return exposedObject;//返回A

返回到createBean

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);//返回到A
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;//返回A
		}

返回doGetBean

				// Create bean instance.
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);//返回A
						}
						
				}

返回到getSingleton

				try {
					singletonObject = singletonFactory.getObject();//返回了A
					newSingleton = true;
				}
				if (newSingleton) {
					addSingleton(beanName, singletonObject);//进入
				}
			return singletonObject;

进入addSingleton(beanName, singletonObject);//进入

	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);//一级缓存存入A
			this.singletonFactories.remove(beanName);//三级缓存清除A
			this.earlySingletonObjects.remove(beanName);//二级缓存清除A
			this.registeredSingletons.add(beanName);//注册A到容器
		}
	}

现在一级缓存有A和B了

a是从一到二到三
b是直接从三到一

返回到getSingleton

				if (newSingleton) {
					addSingleton(beanName, singletonObject);//进入
				}
			return singletonObject;//返回A

返回到doGetBean

				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {//返回
		
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

		return (T) bean;//返回A
				}

返回到getBean

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

返回到preInstantiateSingletons

	public void preInstantiateSingletons() throws BeansException {
				else {
					getBean(beanName);//返回了
				}
			}
		}

		// 退出
	}

退出到finishBeanFactoryInitialization

       
        beanFactory.preInstantiateSingletons();//退出

退出到refresh

		 this.finishRefresh();//返回

到doGetBean

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		String beanName = transformedBeanName(name);
		Object bean;

		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);//A和B循环依赖了
		

跳过debug

Connected to the target VM, address: '127.0.0.1:2121', transport: 'socket'
16:47:13.402 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@63e2203c
16:47:13.749 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 2 bean definitions from class path resource [applicationContext.xml]
16:49:12.840 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'a'
---A created success
17:32:02.337 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'b'
---B created success
Disconnected from the target VM, address: '127.0.0.1:2121', transport: 'socket'

Process finished with exit code 0

38_spring循环依赖debug源码04

再次A / B两对象在三级缓存中的迁移说明

1.A创建过程中需要B,于是A将自己放到三级缓里面,去实例化B。
2.B实例化的时候发现需要A,于是B先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了A然后把三级缓存里面的这个A放到二级缓存里面,并删除三级缓存里面的A。
3.B顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态),然后回来接着创建A,此时B已经创建结束,直接从一级缓存里面拿到B,然后完成创建,并将A自己放到一级缓存里面。

我打的断点
在这里插入图片描述

最后

本文是4.Spring【Java面试第三季】的小节

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/378521.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

守护进程与TCP通讯

目录 一.守护进程 1.1进程组与会画 1.2守护进程 二.创建守护进程 setsid函数&#xff1a; 三. TCP通讯流程 3.1三次握手&#xff1a; 3.2 数据传输的过程 3.3四次挥手 一.守护进程 1.1进程组与会画 进程组&#xff1a;进程组由一个进程或者多个进程组成&#xff0c;每…

谷歌优化排名怎么做出来的?谷歌排名多久做上去?

本文主要分享谷歌排名的算法机制&#xff0c;让你很容易地用更短的时间把Google的自然排名做到首页。 本文由光算创作&#xff0c;有可能会被剽窃和修改&#xff0c;我们佛系对待这种行为吧。 谷歌优化排名怎么做出来的&#xff1f; 答案是&#xff1a;持续更新原创优质内容…

让WPF中的DataGrid像Excel一样可以筛选

在默认情况下&#xff0c;WPF提供的DataGrid仅拥有数据展示等简单功能&#xff0c;如果要实现像Excel一样复杂的筛选过滤功能&#xff0c;则相对比较麻烦。本文以一个简单的小例子&#xff0c;简述如何通过WPF实话DataGrid的筛选功能&#xff0c;仅供学习分享使用&#xff0c;如…

唯品会财报:一面骄阳,一面寒霜

配图来自Canva可画 在互联网技术飞速发展、物流基础设施日益完善&#xff0c;以及消费者购物习惯不断改变等多重因素的共同影响下&#xff0c;电商行业实现了蓬勃发展。得益于此&#xff0c;电商行业也跑出了许多知名电商品牌&#xff0c;其中既有淘宝、京东、拼多多等综合型电…

SSRF漏洞原理、危害以及防御与修复

一、SSRF漏洞原理漏洞概述SSRF&#xff08;Server-side Request Forge&#xff0c;服务端请求伪造&#xff09;是一种由攻击者构造形成由服务端发起请求的安全漏洞。一般情况下&#xff0c;SSRF攻击的目标是从外网无法访问的内部系统。正是因为它是由服务端发起的&#xff0c;所…

Java开发 - Elasticsearch初体验

目录 前言 什么是es&#xff1f; 为什么要使用es&#xff1f; es查询的原理&#xff1f; es需要准备什么&#xff1f; es基本用法 创建工程 添加依赖 创建操作es的文件 使用ik分词插件 Spring Data 项目中引入Spring Data 添加依赖 添加配置 创建操作es的业务逻…

深度学习常用的激活函数总结

各种激活函数总结 目录一、sigmoid二、tanh![在这里插入图片描述](https://img-blog.csdnimg.cn/a0d92552edf8464db793fdd2f2b75cb5.png)三、ReLU系列1.原始ReLU2.ReLU改进&#xff1a;Leaky ReLU四、swish五、GeLU一、sigmoid 优点&#xff1a; 1.可以将任意范围的输出映射到 …

高通平台开发系列讲解(Sensor篇)AlsPs的工作原理及介绍

文章目录 一、什么是ALS?二、什么是距感(PS)?三、AlsPs的工作原理四、AlsPs的特性五、距感的校准参数说明六、光感的校准参数说明沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇文章将介绍 AlsPs 的工作原理及介绍。 一、什么是ALS? 光感的英文叫做Ambient Li…

算法小抄2-刷题中Python的常用语法

标准数据类型 不可变数据类型: Number String Tuple 可变数据类型:List Dictionary Set 关于为什么会分成可变和不可变最后会讲到哦 Number Number支持int,float,bool,complex四种,其中int范围小且必须为整数,float范围较大,可以是是小数,bool值表示是否,complex为复数,赋值…

20- widedeep及函数式构建模型 (TensorFlow系列) (深度学习)

知识要点 wide&deep: 模型构建中, 卷积后数据和原始数据结合进行输出.fetch_california_housing&#xff1a;加利福尼亚的房价数据&#xff0c;总计20640个样本&#xff0c;每个样本8个属性表示&#xff0c;以及房价作为target&#xff0c;所有属性值均为number&#xff0…

网上医疗预约挂号系统

技术&#xff1a;Java、JSP等摘要&#xff1a;网上医疗预约挂号系统是主要是对居民的保健、护理、疾病预防等健康信息实行有效的预约挂号管理。医疗机构为居民建立完整的健康档案&#xff0c;安排体检以及实施免疫等预防措施。而基于Web的远程保健平台以网上医疗预约挂号系统为…

基于OMAPL138+FPGA核心板多核软件开发组件MCSDK开发入门(上)

本文测试板卡为创龙科技 SOM-TL138F 是一款基于 TI OMAP-L138(定点/浮点 DSP C674x + ARM9)+ 紫光同创 Logos/Xilinx Spartan-6 低功耗 FPGA 处理器设计的工业级核心板。核心板内部OMAP-L138 与 Logos/Spartan-6 通过 uPP、EMIFA、I2C 通信总线连接,并通过工业级 B2B连接器引…

分布式任务处理

分布式任务处理 1. 什么是分布式任务调度 视频上传成功需要对视频的格式进行处理&#xff0c;如何用Java程序对视频进行处理呢&#xff1f;这里有一个关键的需求就是当视频比较多的时候我们如何可以高效处理。 如何去高效处理一批任务呢&#xff1f; 1、多线程 多线程是充…

IDEA社区版环境配置和插件安装

一、Java环境安装 1.1 下载openjdk环境安装包 可以进华为镜像站进行下载。参考链接&#xff1a; Index of openjdk-local https://repo.huaweicloud.com/openjdk/ 1.2 配置Java环境 解压缩openjdk到任意路径&#xff0c;建议路径不要有中文。然后把路径的bin文件&#xff0…

新手小白亚马逊注册最全教程在此

自从龙哥出了Walmart注册教程后&#xff0c;立刻看到私信有兄弟问这个亚马逊的注册。亚马逊是跨境电商的鼻祖&#xff0c;资源和流量是无容置疑的。作为一个重产品&#xff0c;轻店铺的平台&#xff0c;是比较看中客户体验的&#xff0c;要求卖家要有好的资源。而且亚马逊有强大…

02-MyBatis查询-

文章目录Mybatis CRUD练习1&#xff0c;配置文件实现CRUD1.1 环境准备Debug01: 别名mybatisx报错1.2 查询所有数据1.2.1 编写接口方法1.2.2 编写SQL语句1.2.3 编写测试方法1.2.4 起别名解决上述问题1.2.5 使用resultMap解决上述问题1.2.6 小结1.3 查询详情1.3.1 编写接口方法1.…

改进YOLOv7-Tiny系列:首发改进结合BiFPN结构的特征融合网络,网络融合更多有效特征,高效涨点

💡该教程为改进进阶指南,属于《芒果书》📚系列,包含大量的原创首发改进方式, 所有文章都是全网首发原创改进内容🚀 内容出品:CSDN博客独家更新 @CSDN芒果汁没有芒果 💡本篇文章 基于 YOLOv5、YOLOv7芒果改进YOLO系列:芒果改进YOLOv7-Tiny系列:首发改进结合BiFPN结…

深度学习笔记:不同的反向传播迭代方法

1 随机梯度下降法SGD 随机梯度下降法每次迭代取梯度下降最大的方向更新。这一方法实现简单&#xff0c;但是在很多函数中&#xff0c;梯度下降的方向不一定指向函数最低点&#xff0c;这使得梯度下降呈现“之”字形&#xff0c;其效率较低 class SGD:"""随机…

springsecurity开启方法级的授权源码分析

1、话不多说&#xff0c;先说使用步骤然后分析源码&#xff1a;首先使用 EnableMethodSecurity 注解开启方法级别的权限认证### 使用该注解开启方法级权限鉴定 EnableMethodSecurity使用了方法权限注解开启了方法级的权限鉴定之后&#xff0c;就可以使用如下注解直接在控制器上…

【微信小程序】-- WXSS 模板样式- rpx import (十三)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…