SpringBoot 源码解析6:Bean的创建① AbstractBeanFactory#doGetBean

1.概述

  1. AbstractBeanFactory#doGetBean方法是Spring创建Bean的核心方法。在此之前Spring已经将BeanDefinition注册到了DefaultListableBeanFactory#beanDefinitionMap。而doGetBean方法会根据BeanDefinition实例化Bean,并且初始化Bean的属性。
  2. AbstractBeanFactory#doGetBean方法是获取Bean的核心入口方法。如果单例池中存在,则返回Bean;不存在,则创建Bean。

2. AbstractBeanFactory#doGetBean源码分析

/**
 * Return an instance, which may be shared or independent, of the specified bean.
 * @param name the name of the bean to retrieve
 * @param requiredType the required type of the bean to retrieve
 * @param args arguments to use when creating a bean instance using explicit arguments
 * (only applied when creating a new instance as opposed to retrieving an existing one)
 * @param typeCheckOnly whether the instance is obtained for a type check,
 * not for actual use
 * @return an instance of the bean
 * @throws BeansException if the bean could not be created
 */
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
		@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

	// 1.转换Bean的名称
	final String beanName = transformedBeanName(name);
	Object bean;

	// Eagerly check singleton cache for manually registered singletons.
	// 2.先校验单例Bean是否已存在,或者手动创建了单例。存在的bean会放在singletonObjects(单例池)中
	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 + "'");
			}
		}
		// 2.1. 从Bean的实例里面获取对象,这里体现了对FactoryBean的兼容性
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 如果当前的Bean没有被实例化,假设在循环依赖里面
		// 3. 循环依赖是不循序原型模式的
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 4.如果当前的Bean工厂中没有注册BeanDefinition,就委派父Bean工厂去实例化
		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) {
			// 5.标记当前Bean已创建
			markBeanAsCreated(beanName);
		}

		try {
			// 6.合并BeanDefinition,将当前的BeanDefinition与当前BeanDefinition中的parentName所指向的BeanDefinition的属性合并。当前的属性覆盖父BeanDefinition的属性
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 7.校验BeanDefinition
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			// 8.处理依赖关系,@DependsOn注解
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				// 8.1.存在依赖的Bean,就先去加载需要依赖的Bean
				for (String dep : dependsOn) {
					// 8.2.判断是否存在循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 8.3.保存Bean的依赖关系
					registerDependentBean(dep, beanName);
					try {
						//8.4.创建所依赖的Bean
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance.
			// 9.创建Bean,单例、原型、其他
			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();
				final 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.
	// 10.校验从Spring中获取的Bean与用户限定的类型是否一致,不一致则抛出异常
	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;
}
  1. 转换Bean的名称,先去掉beanName前缀&,再使用别名获取bean。如果是FactoryBean,那么bean的名称是以"&"开头的。
  2. getObjectForBeanInstance:兼容FactoryBean
    2.1. 跟普通的bean一样,FactoryBean类型的单例创建完毕之后都会保存到单例池。
    2.2. 校验单例Bean是否已存在,存在有两种情况:
    情况1:第一种情况是手动注册到单例池,比如调用DefaultSingletonBeanRegistry#registerSingleton。
    情况2:通过BeanDefinition创建单例。
    但是,不管是哪种情况,创建成功之后都可以通过DefaultSingletonBeanRegistry#getSingleton从Spring的三级缓存中获取。
    2.3. getObjectForBeanInstance方法,通过bean的名称获取bean。
  3. 在Spring中原型模式是不允许循环依赖的。因为ClassA 和 ClassB循环依赖,创建对象的过程为 A1 -> B1 -> A2 -> B2 -> A3 -> B3 -> B4…这样就无法完成Bean的属性的初始化。
  4. 如果当前的Bean工厂中没有注册BeanDefinition,就委派父Bean工厂去实例化。递归。
  5. 标记当前Bean已创建,后面对属性的初始化、代理、三级缓存获取等很多地方都用到了这个标识。
  6. 合并BeanDefinition,将当前的BeanDefinition与当前BeanDefinition中的parentName所指向的BeanDefinition的属性合并。当前的属性覆盖父BeanDefinition的属性。
  7. 校验BeanDefinition,校验了是否为Abstract。
  8. 处理dependsOn。
    8.1 @DependsOn属性解析在AnnotationConfigUtils#processCommonDefinitionAnnotations中完成的。SpringBoot 源码解析5:ConfigurationClassPostProcessor整体流程和@ComponentScan源码分析
    8.2 如果有DependsOn,那么就先实例化DependsOn,两个Bean是不能相互DependsOn。调用getBean方法将所有依赖的Bean创建完毕之后,才创建当前的Bean。注册和校验Bean的依赖关系是通过两个缓存dependentBeanMap和dependenciesForBeanMap完成的。
  9. 支持单例、原型、scope三种方式创建Bean。
  10. 校验通过beanName创建的Bean与限定的类型是否一致,不一致就会抛出异常。因为Spring提供了同时支持beanName和beanType获取Bean。

2.1 转换bean的名称 transformedBeanName

protected String transformedBeanName(String name) {
	return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

//BeanFactoryUtils.transformedBeanName
public static String transformedBeanName(String name) {
	Assert.notNull(name, "'name' must not be null");
	if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
		return name;
	}
	return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
		do {
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
		return beanName;
	});
}

public String canonicalName(String name) {
	String canonicalName = name;
	// Handle aliasing...
	String resolvedName;
	do {
		resolvedName = this.aliasMap.get(canonicalName);
		if (resolvedName != null) {
			canonicalName = resolvedName;
		}
	}
	while (resolvedName != null);
	return canonicalName;
}
  1. 在循环里面将beanName去除所有以"&"开头的字符,添加了缓存transformedBeanNameCache。
  2. 通过去除"&"之后的名称,获取别名。

2.2. FactoryBean兼容

2.2.1 getObjectForBeanInstance
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// Don't let calling code try to dereference the factory if the bean isn't a factory.
	//如果是以&开头,那么需要获取的bean就是factoryBean。
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
		}
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		return beanInstance;
	}

	// Now we have the bean instance, which may be a normal bean or a FactoryBean.
	// If it's a FactoryBean, we use it to create a bean instance, unless the
	// caller actually wants a reference to the factory.
	// 如果不是普通的bean,就直接返回
	if (!(beanInstance instanceof FactoryBean)) {
		return beanInstance;
	}

	Object object = null;
	if (mbd != null) {
		mbd.isFactoryBean = true;
	}
	else {
		//对factoryBean进行缓存,体现了单例factoryBean的特性
		object = getCachedObjectForFactoryBean(beanName);
	}
	if (object == null) {
		// Return bean instance from factory.
		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
		// Caches object obtained from FactoryBean if it is a singleton.
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		//回调factoryBean#getObject获取Bean
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}
  1. 参数说明
    beanInstance:从单例池中获取的bean,这个bean可能是factoryBean
    name:通过getBean方法想要获取bean的名称
    beanName: name去除所有&前缀之后的名称
    mbd: bean的定义信息
  2. 获取factoryBean:用户可以获取factoryBean这个对象,也可以获取factoryBean#getObject方法的返回值的对象。
    1. 如果传入的bean的name是普通的,即不以&开头,获取的对象就是回调factoryBean#getObject方法的返回值,这也是FactoryBean的特性。
    2. 当然,如果用户一定要获取FactoryBean的对象,Spring也是支持的。如果beanName是以&开头,那么Spring就认为用户要获取的对象一定是FactoryBean,即不会回调factoryBean#getObject。并且Spring还校验了这个bean的类型一定是FactoryBean,否则会抛出BeanIsNotAFactoryException。
  3. 如何支持单例:因为每一次调用factoryBean#getObject返回的对象地址是不一样的,为了保证获取的对象是单例,添加了缓存FactoryBeanRegistrySupport#factoryBeanObjectCache。
2.2.2 FactoryBeanRegistrySupport#getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
	if (factory.isSingleton() && containsSingleton(beanName)) {
		synchronized (getSingletonMutex()) {
			Object object = this.factoryBeanObjectCache.get(beanName);
			if (object == null) {
				object = doGetObjectFromFactoryBean(factory, beanName);
				// Only post-process and store if not put there already during getObject() call above
				// (e.g. because of circular reference processing triggered by custom getBean calls)
				Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
				if (alreadyThere != null) {
					object = alreadyThere;
				}
				else {
					if (shouldPostProcess) {
						if (isSingletonCurrentlyInCreation(beanName)) {
							// Temporarily return non-post-processed object, not storing it yet..
							return object;
						}
						beforeSingletonCreation(beanName);
						try {
							object = postProcessObjectFromFactoryBean(object, beanName);
						}
						catch (Throwable ex) {
							throw new BeanCreationException(beanName,
									"Post-processing of FactoryBean's singleton object failed", ex);
						}
						finally {
							afterSingletonCreation(beanName);
						}
					}
					if (containsSingleton(beanName)) {
						this.factoryBeanObjectCache.put(beanName, object);
					}
				}
			}
			return object;
		}
	}
	else {
		Object object = doGetObjectFromFactoryBean(factory, beanName);
		if (shouldPostProcess) {
			try {
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
			}
		}
		return object;
	}
}
  1. 这是从FactoryBean获取Bean具体方法。
  2. 分为单例和非单例。如果是单例,使用了缓存。非单例,就没有放入缓存,直接创建bean。FactoryBean#getObject具体回调是在FactoryBeanRegistrySupport#doGetObjectFromFactoryBean中完成的。
2.2.3 Demo

虽然本系列只是做源码分析,还是写一个demo吧!!!

FactoryBean

@Component
public class FactoryBeanTest implements FactoryBean<Object> {

    @Override
    public Object getObject() throws Exception {
        return new Object();
    }

    @Override
    public Class<?> getObjectType() {
        return Object.class;
    }
}

启动类

public static void main(String[] args) {
     ConfigurableApplicationContext run = SpringApplication.run(MyApplication.class, args);
     Object obj = run.getBean("factoryBeanTest");
     System.out.println(obj.getClass());
     Object factoryBean = run.getBean("&factoryBeanTest");
     System.out.println(factoryBean.getClass());
 }

可以看到,factoryBeanTest打印的是回调getObject之后的bean,而&factoryBeanTest打印的就是FactoryBean的本身。

在这里插入图片描述

2.3 三级缓存

2.3.1 属性
/** 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 HashMap<>(16);

这三个Map的key都为beanName

  1. singletonObjects :一级缓存,存放的值为Bean。并且bean中的属性已初始化完毕。@Autowired、@Resource注解处理完毕。
  2. earlySingletonObjects : 二级缓存,存放的为Bean。但是Bean中的属性可能没有初始化,也有可能初始化了一部分。
  3. singletonFactories :三级缓存,存放的为ObjectFactory。通过源码看ObjectFactory是FunctionalInterface。回调该函数式接口才能返回Bean。

面试题:为什么需要三级缓存singletonFactories?代理。三级缓存里面判断是否有代理对象,有代理对象就返回单例对象(没有就返回当前对象),放入到二级缓存。AbstractAutoProxyCreator#earlyProxyReferences中缓存了代理的对象。

2.3.2 从缓存中获取
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	//1.从一级缓存中获取Bean
	Object singletonObject = this.singletonObjects.get(beanName);
	//一级缓存中不存在,并且当前的Bean是单例并且正在创建中
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		synchronized (this.singletonObjects) {
			//2.从二级缓存中获取
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				//3.获取三级缓存
				ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
				if (singletonFactory != null) {
					//回调三级缓存
					singletonObject = singletonFactory.getObject();
					//放入三级缓存
					this.earlySingletonObjects.put(beanName, singletonObject);
					//移除二级缓存
					this.singletonFactories.remove(beanName);
				}
			}
		}
	}
	return singletonObject;
}

源码解析如注释。逐级获取, 一级缓存 -> 二级缓存 -> 三级缓存。
三级缓存是FunctionalInterface,如下

@FunctionalInterface
public interface ObjectFactory<T> {

	/**
	 * Return an instance (possibly shared or independent)
	 * of the object managed by this factory.
	 * @return the resulting instance
	 * @throws BeansException in case of creation errors
	 */
	T getObject() throws BeansException;

}
2.3.3 添加缓存
/**
 * Add the given singleton object to the singleton cache of this factory.
 * <p>To be called for eager registration of singletons.
 * @param beanName the name of the bean
 * @param singletonObject the singleton object
 */
protected void addSingleton(String beanName, Object singletonObject) {
	synchronized (this.singletonObjects) {
		//添加一级缓存,移除二级、三级缓存
		this.singletonObjects.put(beanName, singletonObject);
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

/**
 * 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);
		}
	}
}
  1. addSingleton添加一级缓存,将二级、三级缓存清除。
  2. addSingletonFactory添加三级缓存,首先判断了一级缓存中是否存在,不存在则添加三级缓存,并且移除二级缓存。
  3. 可以简单的理解为同一时间只会保存在一个缓存。

ObjectFactory是一个函数接口:

@FunctionalInterface
public interface ObjectFactory<T> {
	T getObject() throws BeansException;
}

三级缓存中保存的是getEarlyBeanReference方法:

if (earlySingletonExposure) {
	if (logger.isTraceEnabled()) {
		logger.trace("Eagerly caching bean '" + beanName +
				"' to allow for resolving potential circular references");
	}
	addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

可以看到回调了SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法:

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;
}

AbstractAutoProxyCreator#getEarlyBeanReference可以获取代理对象。

2.4 @DependsOn原理

2.4.1 @DependsOn注解解析

扫描到一个Bean需要被Spring管理后,就会生成Bean的定义信息,也就是BeanDefinition。而DependsOn的属性也会封装到BeanDefinition中。

想要知道一个Bean是否要被Spring管理,请参考@ComponentScan原理。SpringBoot 源码解析5:ConfigurationClassPostProcessor整体流程和@ComponentScan源码分析

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
	AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
	if (lazy != null) {
		abd.setLazyInit(lazy.getBoolean("value"));
	}
	else if (abd.getMetadata() != metadata) {
		lazy = attributesFor(abd.getMetadata(), Lazy.class);
		if (lazy != null) {
			abd.setLazyInit(lazy.getBoolean("value"));
		}
	}

	if (metadata.isAnnotated(Primary.class.getName())) {
		abd.setPrimary(true);
	}
	AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
	if (dependsOn != null) {
		abd.setDependsOn(dependsOn.getStringArray("value"));
	}

	AnnotationAttributes role = attributesFor(metadata, Role.class);
	if (role != null) {
		abd.setRole(role.getNumber("value").intValue());
	}
	AnnotationAttributes description = attributesFor(metadata, Description.class);
	if (description != null) {
		abd.setDescription(description.getString("value"));
	}
}

可以看到最终将DependsOn#value中的属性封装到AbstractBeanDefinition#dependsOn。而这些属性就是bean的名称。

2.4.2 depends属性应用
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);
		}
	}
}
  1. 如果两个bean相互依赖,就会抛出异常。因为Spring的规则就是dependsOn的bean要先创建,如果相互依赖,Spring不知道优先创建哪一个bean。
  2. 在创建Bean的时候AbstractBeanFactory#doGetBean方法会优先加载AbstractBeanDefinition#dependsOn对应的bean,再创建当前的bean。
2.4.3 依赖关系管理 DefaultSingletonBeanRegistry#registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
	String canonicalName = canonicalName(beanName);

	synchronized (this.dependentBeanMap) {
		Set<String> dependentBeans =
				this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
		if (!dependentBeans.add(dependentBeanName)) {
			return;
		}
	}

	synchronized (this.dependenciesForBeanMap) {
		Set<String> dependenciesForBean =
				this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
		dependenciesForBean.add(canonicalName);
	}
}
  1. 参数说明:
    beanName:依赖的bean名称
    dependentBeanName:当前正在创建的bean的名称
  2. Spring对一个Bean的依赖关系也进行了管理。其实不仅仅是对@DependsOn注解的关系,一个Bean的属性依赖另外一个bean也是通过这种方式进行管理的。
  3. 这种关系通过两个map进行管理。
    dependentBeanMap:如果A依赖B,那么key为B,value为A。
    dependenciesForBeanMap:如果A依赖B,那么key为A,value为B。
### Python `self.rules` Equals `self.make_rules()` Method Implementation and Issues In object-oriented programming with Python, the use of methods like `self.rules = self.make_rules()` is common when initializing or updating attributes within an instance based on specific rules defined by another method. This pattern ensures encapsulation and separation of concerns. The line `self.rules = self.make_rules()` suggests that: - An attribute named `rules` belongs to each instance (`self`) of a class. - The value assigned to this attribute comes from calling the method `make_rules`. Here's how one can implement such functionality properly using best practices in Python[^1]: ```python class RuleBasedSystem: def __init__(self): # Initialize other necessary variables here # Call make_rules during initialization self.rules = self.make_rules() def make_rules(self): """ Defines logic for creating rule set. Returns: A data structure containing all applicable rules (e.g., list, dict). """ # Logic to create rules goes here return { "rule_1": True, "rule_2": False, # Add more rules as needed } ``` Common issues encountered while implementing similar patterns include: - **Initialization Order**: Ensuring proper order between defining properties and invoking methods which depend on those properties. - **Method Visibility**: Making sure that any helper functions used internally are not exposed unnecessarily outside the class unless intended. - **Error Handling**: Incorporating robust error handling mechanisms inside `make_rules`, especially if it depends on external resources or user inputs. To address these challenges effectively, consider adding checks before setting up `self.rules`. For example, validating input parameters passed into `__init__` or ensuring dependencies required by `make_rules` exist prior to execution. --related questions-- 1. How does Python handle inheritance concerning private members? 2. What strategies should be adopted to manage complex state transitions within objects efficiently? 3. Can you provide examples where improper initialization leads to bugs in Python classes? 4. In what scenarios would static methods versus class methods better suit designing utility functions related to rule creation?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值