春の原理学習シリーズ6:登録のBeanDefinition IOC原理

入門

前回の記事では、我々は一般的に紹介はBean、作成Bean潮流を、しかし、記事ではなく、細部のすべての方法限られたスペースに起因します。このシリーズの以降の記事はのようになり、このPaodingjieniuの内容の一部となりIOC、より重要な詳細は自分自身に明確にし、読者がため深めることができます。この記事で読むのに時間を取るためにSpring IOC深い理解を。

  • BeanDefinition
  • BeanDefinitionRegistry
  • 概要

まず、BeanDefinition

ナニは、あなたが言っているSpring IOC記事は、あなたが十分なことを言っていない前に、?
ここに画像を挿入説明
Springに関するIOC記事の前でそんなにそれのこのセクションの内容は、また非常に細かい言いませんでした。それだけでしつこい遅くし続けることができます。ADOは、続けていきましょうIOC

BeanDefinition記述するために使用され、パックデータ構造を豆です。そのソースコードを以下に示します。SpringBean

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();

	

}

それを見ることができるプロパティとメソッドの上記の分析から、BeanDefinitionのためにBean説明制約のより完全なセットを作りました。これは、その後の実装クラスのための最も基本的な責任と属性を提供します。BeanDefinition次のようにするだけのインターフェース、その具体的な実装は、次のとおりです。
ここに画像を挿入説明

II。BeanDefinitionRegistry

BeanDefinitionRegistry継承AliasRegistry:インタフェースは、コアは3つのサブクラスを有しSimpleBeanDefinitionRegistryDefaultListableBeanFactoryそしてGenericApplicationContext図クラス機構に示すように、:汎用の主な機能であるトップレベルインターフェースは、エイリアスマネージャ、インタフェース管理方法定義されたいくつかのエイリアスを。
ここに画像を挿入説明
AliasRegistryBeanDefinitionRegistryAliasRegistry

public interface AliasRegistry {

	
	void registerAlias(String name, String alias);

	
	void removeAlias(String alias);

	
	boolean isAlias(String name);


	String[] getAliases(String name);

}

BeanDefinitionRegistryインターフェイスは、達成するためにAliasRegistryも、上に定義された外部のBeanDefinition事業登録、キャンセル、お問い合わせのシリーズ。

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

}

私たちは見ることができますBeanDefinitionRegistry実装構造は、以下に示すことをクラス:

ここに画像を挿入説明
ここでの実装クラスの下の懸念GenericApplicationContextのためのより多くの重要な方法registerBeanDefinition、それが完了するまでBeanDefinition登録を:

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

実際の登録プロセスの登録操作を完了するために:DefaultListableBeanFactoryregisterBeanDefinition

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

実際には、上記のコードはあまり最も重要なものです:

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

this.beanDefinitionMap.put(beanName, beanDefinition);

III。总结

本稿では、説明BeanDefinition及びBeanDefinition登録BeanDefinitionされたSpring処理Bean、統一データ構造をBeanDefinitionRegistryする実装クラスをBeanDefinition登録操作を完了、登録最終結果は、に格納されbeanDefinitionMap、このConcurrentHashMap媒体。ここに今日の内容、我々は次の時間、ああ。
ここに画像を挿入説明

88元記事公開 ウォン称賛49 ビューに10万+を

おすすめ

転載: blog.csdn.net/Diamond_Tao/article/details/103484170