第三章 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
解讀
- 可能會獲得三種不同的類載入器
- 在不同應用中,spring的類載入器,可能不其他的類載入器 不一樣。比如在tomcat容器中,獲得的類載入器與spring預設類載入器不一樣
- 不建議修改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));
}
.....
}
解讀
- 如果沒有配置 ConversionService 子類,預設在容器裡面是沒有ConversionService實現類的getConversionService返回null
- 關於 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;
}
解讀
- beanPostProcessors變數儲存了所有BeanPostProcessor實現類,
- 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);
}
}
解讀
- 不建議修改cacheBeanMetadata的值
- mergedBeanDefinitions儲存了RootBeanDefinition物件,RootBeanDefinition物件才會生成一個物件。其他的beanDefinition實現不會。奇怪的設計。
- alreadyCreated控制RootBeanDefinition併發建立問題
總結
本節的內容感覺比較慘白無力,有些細節點還是比較重要的。比如RootBeanDefinition,ConversionService,ClassLoad等。其他方面鳥菜啊,感覺就是無用就不解讀了。