1. 程式人生 > >第三章 spring-bean之AbstractBeanFactory(5)

第三章 spring-bean之AbstractBeanFactory(5)

前言

AbstractBeanFactor實現了ConfigurableBeanFactory介面。一棵樹有不僅有主幹,樹幹,還有花花葉葉。其他介面與實現是BeanFactory的主幹與樹幹的話,那ConfigurableBeanFactory負責管理BeanFactory的花花葉葉。

    void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;

	void setBeanClassLoader(ClassLoader beanClassLoader);

	ClassLoader getBeanClassLoader();

	void setTempClassLoader(ClassLoader tempClassLoader);

	ClassLoader getTempClassLoader();

	void setCacheBeanMetadata(boolean cacheBeanMetadata);

	boolean isCacheBeanMetadata();

	void setBeanExpressionResolver(BeanExpressionResolver resolver);

	BeanExpressionResolver getBeanExpressionResolver();

	void setConversionService(ConversionService conversionService);

	ConversionService getConversionService();

	void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);

	void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);

	void copyRegisteredEditorsTo(PropertyEditorRegistry registry);

	void setTypeConverter(TypeConverter typeConverter);

	TypeConverter getTypeConverter();

	void addEmbeddedValueResolver(StringValueResolver valueResolver);

	boolean hasEmbeddedValueResolver();

	String resolveEmbeddedValue(String value);

	void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

	int getBeanPostProcessorCount();

	void registerScope(String scopeName, Scope scope);

	String[] getRegisteredScopeNames();

	Scope getRegisteredScope(String scopeName);

	AccessControlContext getAccessControlContext();

	void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);

	void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;

	void resolveAliases(StringValueResolver valueResolver);

	BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;

	void setCurrentlyInCreation(String beanName, boolean inCreation);

	boolean isCurrentlyInCreation(String beanName);

	void registerDependentBean(String beanName, String dependentBeanName);

	String[] getDependentBeans(String beanName);

	String[] getDependenciesForBean(String beanName);
關於parentBeanFactory 變數相關資訊
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
private BeanFactory parentBeanFactory;

呼叫方

  • org.springframework.beans.factory.support.AbstractBeanFactory
    • containsBean(String)
    • doGetBean(String, Class<T>, Object[], boolean)
    • getAliases(String)
    • getMergedBeanDefinition(String, BeanDefinition, BeanDefinition)
    • getMergedBeanDefinition(String)
    • getType(String)
    • isFactoryBean(String)
    • isPrototype(String)
    • isSingleton(String)
    • isTypeMatch(String, ResolvableType)
  • org.springframework.beans.factory.support.DefaultListableBeanFactory
    • checkBeanNotOfRequiredType(Class<?>, DependencyDescriptor)
    • getBean(Class<T>, Object...)
    • isAutowireCandidate(String, DependencyDescriptor, AutowireCandidateResolver)
    • isPrimary(String, Object)
    • resolveNamedBean(Class<T>)
    • toString()

從被呼叫的方法名可以方法,parentBeanFactory屬性主要是在得到或建立bean的時候,需要進行同樣的操作。比如getBean方法,在當前beanFactory沒有得到bean,就會去parentBeanFactory執行getBean(){去操作同樣的方法}。

public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
		NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
		if (namedBean != null) {
			return namedBean.getBeanInstance();
		}
		BeanFactory parent = getParentBeanFactory();
		if (parent != null) {
			return parent.getBean(requiredType, args);
		}
		throw new NoSuchBeanDefinitionException(requiredType);
	}

解讀

parentBeanFactory的設計主要是解決在複雜環境的下,當前容器有parent容器的情況。但是這種設計在當前網際網路與分散式應用中無法應用到,所以是一個。菜鳥啊個人,感覺這個功能已經十分過時了。

關於ClassLoader相關變數

void setBeanClassLoader(ClassLoader beanClassLoader);

private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();

public static ClassLoader getDefaultClassLoader() {
		ClassLoader cl = null;
		try {
			cl = Thread.currentThread().getContextClassLoader();
		}
		catch (Throwable ex) {
			// Cannot access thread context ClassLoader - falling back...
		}
		if (cl == null) {
			// No thread context class loader -> use class loader of this class.
			cl = ClassUtils.class.getClassLoader();
			if (cl == null) {
				// getClassLoader() returning null indicates the bootstrap ClassLoader
				try {
					cl = ClassLoader.getSystemClassLoader();
				}
				catch (Throwable ex) {
					// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
				}
			}
		}
		return cl;
	}

org.springframework.aop.aspectj org.springframework.aop.aspectj.annotation org.springframework.aop.config org.springframework.aop.scope org.springframework.beans.factory.support org.springframework.context.annotation org.springframework.context.event org.springframework.context.expression org.springframework.context.support org.springframework.remoting.jaxws

解讀

  1. 可能會獲得三種不同的類載入器
  2. 在不同應用中,spring的類載入器,可能不其他的類載入器 不一樣。比如在tomcat容器中,獲得的類載入器與spring預設類載入器不一樣
  3. 不建議修改beanClassLoader類載入器的值

conversionService 變數

private ConversionService conversionService;

public void setConversionService(ConversionService conversionService) {
	this.conversionService = conversionService;
}

@Override
public ConversionService getConversionService() {
	return this.conversionService;
}
}
String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	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));
	}
	.....
} 

解讀

  1. 如果沒有配置 ConversionService 子類,預設在容器裡面是沒有ConversionService實現類的getConversionService返回null
  2. 關於 ConversionService 的詳解請求第二章 二節spring-core之converter深入解讀

關於BeanPostProcessor相關的變數

private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();

/** Indicates whether any InstantiationAwareBeanPostProcessors have been registered */
private boolean hasInstantiationAwareBeanPostProcessors;

/** Indicates whether any DestructionAwareBeanPostProcessors have been registered */
private boolean hasDestructionAwareBeanPostProcessors;

public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
		Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
		this.beanPostProcessors.remove(beanPostProcessor);
		this.beanPostProcessors.add(beanPostProcessor);
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
}

public int getBeanPostProcessorCount() {
	return this.beanPostProcessors.size();
}

public List<BeanPostProcessor> getBeanPostProcessors() {
	return this.beanPostProcessors;
}

protected boolean hasInstantiationAwareBeanPostProcessors() {
	return this.hasInstantiationAwareBeanPostProcessors;
}

protected boolean hasDestructionAwareBeanPostProcessors() {
	return this.hasDestructionAwareBeanPostProcessors;
}

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
	Object exposedObject = bean;
	if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
				SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
				exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
				if (exposedObject == null) {
					return null;
				}
			}
		}
	}
	return exposedObject;
}



解讀

  1. beanPostProcessors變數儲存了所有BeanPostProcessor實現類,
  2. hasDestructionAwareBeanPostProcessors與hasDestructionAwareBeanPostProcessors的作用是避免進行無效的迴圈操作

RootBeanDefinition相關變數

	private boolean cacheBeanMetadata = true;

	protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, BeanDefinition containingBd)throws BeanDefinitionStoreException {
		if (containingBd == null && isCacheBeanMetadata()) {
			this.mergedBeanDefinitions.put(beanName, mbd);
		}
	}


	private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<String, RootBeanDefinition>(256);

	private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(256));
	protected void markBeanAsCreated(String beanName) {
		if (!this.alreadyCreated.contains(beanName)) {
			synchronized (this.mergedBeanDefinitions) {
				if (!this.alreadyCreated.contains(beanName)) {
					clearMergedBeanDefinition(beanName);
					this.alreadyCreated.add(beanName);
				}
			}
		}
	} 
	protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
		if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}
		try {
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);
		}
	}

解讀

  1. 不建議修改cacheBeanMetadata的值
  2. mergedBeanDefinitions儲存了RootBeanDefinition物件,RootBeanDefinition物件才會生成一個物件。其他的beanDefinition實現不會。奇怪的設計。
  3. alreadyCreated控制RootBeanDefinition併發建立問題

總結

本節的內容感覺比較慘白無力,有些細節點還是比較重要的。比如RootBeanDefinition,ConversionService,ClassLoad等。其他方面鳥菜啊,感覺就是無用就不解讀了。