ApplicationContext.2 prepareBeanFactory以及propertyEditor解析

141 阅读2分钟

0.主要功能

  1. 注册el表达式解析器,beanclassLoaderPropertyEditorRegistrar
  2. 新增ApplicationContextAwareProcessor(BeanPostProcessor,处理各种Aware接口的set方法调用)
  3. 配置类型转化相关的PropertyEditor
  4. 设置被忽略的依赖注册(也就是属于这些接口的类型属性的不会注入任何bean
  5. 注册一些组件为特殊依赖项,比如beanFactory本身不会是一个bean,当一个bean需要的时候,如何注入。就是把这些依赖项 存在到一个缓存中
  6. 注册Env bean

1. 代码流程解析

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());
	//设置el表达式解析器
	beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
	//新增一个propertyEditor注册中心(设置后,具体是在什么地方被调用,如何获取,怎么调用)
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	//配置BeanProcessor,用于在实现Aware接口的bean初始化后,调用器接口方法
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	//Ignore the given dependency interface for autowiring
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
	//设置一些解析过的autowired对象,后续处理该类对象的autowire的时候,可以直接查询注入.不需要在从beanbectory中查找处理
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// Register default environment beans.
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

2. beanFactory.addPropertyEditorRegistrar()的使用

/*--org.springframework.beans.factory.support.AbstractBeanFactory--*/
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
	Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
	this.propertyEditorRegistrars.add(registrar);
}

this.propertyEditorRegistrar的定义如下

private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
			new LinkedHashSet<PropertyEditorRegistrar>(4);

那么该属性会在什么时候调用呢?典型的用法在org.springframework.beans.factory.support.AbstractBeanFactory#registerCustomEditors.

protected void registerCustomEditors(PropertyEditorRegistry registry) {
	PropertyEditorRegistrySupport registrySupport =
			(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
	..
	if (!this.propertyEditorRegistrars.isEmpty()) {
		for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
			try {
			    //addPropertyEditorRegistrar中增加的`PropertyEditorRegistrar`调用。
				registrar.registerCustomEditors(registry);
			}
			catch (BeanCreationException ex) {
			..
			}
		}
	}
..
}

registerCustomEditors方法会用来在 beanpopulate property的处理中,给BeanWrapper配置默认的propertyEditor

/**--AbstractBeanFactory--**/
protected void initBeanWrapper(BeanWrapper bw) {
	bw.setConversionService(getConversionService());
	registerCustomEditors(bw);
}
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if (System.getSecurityManager() != null) {
			...
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			...
		}
	}

在实例化instantiateBean后,随后的工作就是populate property

2.1PropertyEditorRegistrar 解析

PropertyEditorRegistrar的接口的目的是操作PropertyEditorRegistry,为其注入一些自定义的PropertyEditor,目的是避免重复代码,将各类默认的propertyEditor注入到各类PropertyEditorRegistry,为功能接口,定义如下。

public interface PropertyEditorRegistrar {
	void registerCustomEditors(PropertyEditorRegistry registry);

}

参考实现ResourceEditorRegistrar,.

public void registerCustomEditors(PropertyEditorRegistry registry) {
	ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
	doRegisterEditor(registry, Resource.class, baseEditor);
	doRegisterEditor(registry, ContextResource.class, baseEditor);
	doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
	doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
	doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
	doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));

	ClassLoader classLoader = this.resourceLoader.getClassLoader();
	doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
	doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
	doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));

	if (this.resourceLoader instanceof ResourcePatternResolver) {
		doRegisterEditor(registry, Resource[].class,
				new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
	}
}

2.3 如何注入自定义的propertyEditor

使用CustomEditorConfigurer类,该类实现BeanFactoryPostProcessor,再beanFactory加载完成后,执行将自定义的propertyEditor注册到beanFactory中。