Principio de primavera aprendizaje de la serie Seis: principio BeanDefinition COI de la inscripción

introducción

En el artículo anterior, por lo general introduce Beancreamos, Beanflujo de carga, pero debido al espacio limitado del artículo, no todo tipo de detalles. Los siguientes artículos de esta serie serán parte de los contenidos de esta Paodingjieniu, al igual que IOClos detalles más importantes dejan claro a nosotros mismos y tomar el tiempo de leer este artículo, el lector puede profundizar Para Spring IOCla comprensión en profundidad.

  • BeanDefinition
  • BeanDefinitionRegistry
  • resumen

En primer lugar,BeanDefinition

Nani, que tiene que decir Spring IOC, antes de que el artículo no se ha dicho lo suficiente cosa?
Aquí Insertar imagen Descripción
Quien Springen relación con IOCel contenido de esta sección por lo que gran parte de ella, frente al artículo también no dijo muy bien. Sólo se puede seguir para reducir la velocidad persistente. Preámbulos, vamos a continuar IOC.

BeanDefinitionSe utiliza para describir Springla Beanestructura de datos de paquete es el Bean. Su código fuente se muestra a continuación:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

	
	//标准单例作用域的作用域标识符:“singleton”,对于扩展的bean工厂可能支持更多的作用域
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

	//标准原型作用域的范围标识符:“prototype”
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


	//表示BeanDefinition是应用程序主要部分的角色提示,通常对应于用户定义的bean
	int ROLE_APPLICATION = 0;

	//表示BeanDefinition是某些大型配置的支持部分的角色提示,通常是一个外部ComponentDefinition。
	//当查看某个特定的ComponentDefinition时,认为bean非常重要,
	//以便在查看应用程序的整体配置时能够意识到这一点
	int ROLE_SUPPORT = 1;

	//角色提示表明一个BeanDefinition是提供一个完全背景的角色,并且与最终用户没有关系。
	//这个提示用于注册完全是ComponentDefinition内部工作的一部分的bean
	int ROLE_INFRASTRUCTURE = 2;

	//1、当前Bean父类名称
	//如果父类存在,设置这个bean定义的父定义的名称
	void setParentName(@Nullable String parentName);

	//如果父类存在,则返回当前Bean的父类的名称
	@Nullable
	String getParentName();

	//2、当前Bean的className
	//指定此bean定义的bean类名称。
	//类名称可以在bean factory后期处理中修改,通常用它的解析变体替换原来的类名称
	void setBeanClassName(@Nullable String beanClassName);

	//返回此bean定义的当前bean类名称
	//需要注意的是,这不一定是在运行时使用的实际类名,以防子类定义覆盖/继承其父类的类名
	//此外,这可能只是调用工厂方法的类,或者它 在调用方法的工厂bean引用的情况下甚至可能是空的
	//因此,不要认为这是在运行时定义的bean类型,而只是将其用于在单独的bean定义级别进行解析
	@Nullable
	String getBeanClassName();

	//3、bean作用域
	//覆盖此bean的目标范围,指定一个新的范围名称
	void setScope(@Nullable String scope);

	//返回此bean的当前目标作用域的名称,如果没有确定,返回null
	@Nullable
	String getScope();

	//懒加载
	//设置这个bean是否应该被延迟初始化。如果{false},那么这个bean将在启动时由bean工厂实例化,
	//这些工厂执行单例的立即初始化。
	//懒加载 <bean lazy-init="true/false">
	void setLazyInit(boolean lazyInit);

	//返回这个bean是否应该被延迟初始化,即不是在启动时立即实例化。只适用于单例bean。
	boolean isLazyInit();

	//5.依赖关系设置
	//设置这个bean依赖被初始化的bean的名字。 bean工厂将保证这些bean首先被初始化。
	//<bean depends-on="">
	void setDependsOn(@Nullable String... dependsOn);

	//返回这个bean依赖的bean名称
	@Nullable
	String[] getDependsOn();

	//6.是否是自动转配设置
	//设置这个bean是否是获得自动装配到其他bean的候选人。
	//需要注意是,此标志旨在仅影响基于类型的自动装配。
	//它不会影响按名称的显式引用,即使指定的bean没有标记为autowire候选,也可以解决这个问题。
	//因此,如果名称匹配,通过名称的自动装配将注入一个bean。
	void setAutowireCandidate(boolean autowireCandidate);

	//返回这个bean是否是自动装配到其他bean的候选者。就是是否在其他类中使用autowired来注入当前Bean的
	//是否为被自动装配 <bean autowire-candidate="true/false">
	boolean isAutowireCandidate();

	//7.主候选Bean
	//是否为主候选bean    使用注解:@Primary
	
	void setPrimary(boolean primary);
	
	//返回这个bean是否是主要的autowire候选者
	boolean isPrimary();

	//8.定义创建该Bean对象的工厂类
	//指定要使用的工厂bean(如果有的话), 这是调用指定的工厂方法的bean的名称
	void setFactoryBeanName(@Nullable String factoryBeanName);

	//如果有返回工厂bean的名字
	@Nullable
	String getFactoryBeanName();

	//9.创建该Bean对象的工厂方法
	//如果有,指定工厂方法。这个方法先将通过构造函数参数被调用,或者如果参数,将调用该方法的无参数构造
	void setFactoryMethodName(@Nullable String factoryMethodName);
	//如果存在,返回工厂方法名
	@Nullable
	String getFactoryMethodName();

	//10.返回此bean的构造函数参数值
	//返回此bean的构造函数参数值
	ConstructorArgumentValues getConstructorArgumentValues();

	default boolean hasConstructorArgumentValues() {
		return !getConstructorArgumentValues().isEmpty();
	}

	//11.获取属性
	MutablePropertyValues getPropertyValues();

	default boolean hasPropertyValues() {
		return !getPropertyValues().isEmpty();
	}

	//12.设置初始方法
	void setInitMethodName(@Nullable String initMethodName);

	@Nullable
	String getInitMethodName();


	void setDestroyMethodName(@Nullable String destroyMethodName);

	@Nullable
	String getDestroyMethodName();


	void setRole(int role);

	//13.当前Bean的角色
	//获取这个bean的角色
	int getRole();

	void setDescription(@Nullable String description);

	//14.可读描述
	//返回对bean定义的可读描述
	@Nullable
	String getDescription();

	//返回该bean定义来自的资源的描述
	@Nullable
	String getResourceDescription();

	//返回原始的BeanDefinition;如果没有,则返回null。允许检索装饰的bean定义
	@Nullable
	BeanDefinition getOriginatingBeanDefinition();
	
	//15.当前Bean的基本特性
	//是否是单例的
	boolean isSingleton();

	//是否是多例的
	boolean isPrototype();

	//是否是抽象类
	boolean isAbstract();

	

}

Del análisis anterior de las propiedades y métodos se puede ver, BeanDefinitionpara un Beandescripción hecha conjunto más completo de restricciones. Esto proporciona las responsabilidades más básicas y atributos para la posterior implementación de la clase. BeanDefinitionSólo una interfaz, su aplicación específica es la siguiente:
Aquí Insertar imagen Descripción

II.BeanDefinitionRegistry

BeanDefinitionRegistryLa herencia de AliasRegistrylas interfaces, el núcleo tiene tres subclases: SimpleBeanDefinitionRegistry, DefaultListableBeanFactoryy GenericApplicationContext, como se muestra en la figura mecanismo de la clase:
Aquí Insertar imagen Descripción
AliasRegistryuna BeanDefinitionRegistryinterfaz de nivel superior, que es la función principal de la de propósito general interconecta Alias Manager, AliasRegistryalgunos alias definidos métodos de gestión.

public interface AliasRegistry {

	
	void registerAlias(String name, String alias);

	
	void removeAlias(String alias);

	
	boolean isAlias(String name);


	String[] getAliases(String name);

}

BeanDefinitionRegistryInteractuar para lograr AliasRegistryexterior también definida en BeanDefinitionuna serie de operaciones de registro, cancelación, la indagación.

public interface BeanDefinitionRegistry extends AliasRegistry {

	// 向注册表中注册一个新的 BeanDefinition 实例
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	 // 移除注册表中已注册的 BeanDefinition 实例
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	 // 从注册中取得指定的 BeanDefinition 实例
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	 // 判断 BeanDefinition 实例是否在注册表中(是否注册)
	boolean containsBeanDefinition(String beanName);

	// 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
	String[] getBeanDefinitionNames();

	// 返回注册表中 BeanDefinition 实例的数量
	int getBeanDefinitionCount();

	// beanName(标识)是否被占用
	boolean isBeanNameInUse(String beanName);

}

Podemos mirar a BeanDefinitionRegistryuna clase que implementa la estructura que se muestra a continuación:

Aquí Insertar imagen Descripción
La preocupación aquí bajo clase de implementación GenericApplicationContext, la forma más importante para registerBeanDefinitionque se complete la BeanDefinitioninscripción:

public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {

	private final DefaultListableBeanFactory beanFactory;
	
	...
	
	@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
	}
	...
}

El proceso de registro real de DefaultListableBeanFactoryla registerBeanDefinitionpara completar la acción de registro:

@Override
	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
		else {
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					if (this.manualSingletonNames.contains(beanName)) {
						Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
						updatedSingletons.remove(beanName);
						this.manualSingletonNames = updatedSingletons;
					}
				}
			}
			else {
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				this.manualSingletonNames.remove(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
	}

De hecho, el código anterior es tanto lo más importante:

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

this.beanDefinitionMap.put(beanName, beanDefinition);

III.总结

En este trabajo se describe BeanDefinitiony BeanDefinitionregistro, BeanDefinitionse Springencarga de Beanuna estructura de datos unificada, BeanDefinitionRegistryla clase de implementación para BeanDefinitioncompletar la operación de registro, el resultado final de registro se almacena en beanDefinitionMapeste ConcurrentHashMapmedio. el contenido de hoy aquí, que la próxima vez, oh.
Aquí Insertar imagen Descripción

Publicado 88 artículos originales · ganado elogios 49 · Vistas de 100.000 +

Supongo que te gusta

Origin blog.csdn.net/Diamond_Tao/article/details/103484170
Recomendado
Clasificación