Spring getBean的时候,在构造BeanWrapperImpl时候会注册PropertyEditor,代码如下:
AbstractAutowireCapableBeanFactory类中的方法:
[code="java"]
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
[/code]
在调用上述方法initBeanWrapper(bw);时,initBeanWrapper方法代码如下(该方法在AbstractBeanFactory中):
[code="java"]
protected void initBeanWrapper(BeanWrapper bw) {
registerCustomEditors(bw);
}
[/code]
registerCustomEditors(bw);代码如下:
[code="java"]
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport =
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
if (!this.propertyEditorRegistrars.isEmpty()) {
for (Iterator it = this.propertyEditorRegistrars.iterator(); it.hasNext();) {
PropertyEditorRegistrar registrar = (PropertyEditorRegistrar) it.next();
try {
registrar.registerCustomEditors(registry);
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
"] failed because it tried to obtain currently created bean '" + ex.getBeanName() +
"': " + ex.getMessage());
}
onSuppressedException(ex);
continue;
}
}
throw ex;
}
}
}
if (!this.customEditors.isEmpty()) {
for (Iterator it = this.customEditors.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Class requiredType = (Class) entry.getKey();
Object value = entry.getValue();
if (value instanceof PropertyEditor) {
PropertyEditor editor = (PropertyEditor) value;
// Register the editor as shared instance, if possible,
// to make it clear that it might be used concurrently.
if (registrySupport != null) {
registrySupport.registerSharedEditor(requiredType, editor);
}
else {
registry.registerCustomEditor(requiredType, editor);
}
}
else if (value instanceof Class) {
Class editorClass = (Class) value;
registry.registerCustomEditor(requiredType, (PropertyEditor) BeanUtils.instantiateClass(editorClass));
}
else {
throw new IllegalStateException("Illegal custom editor value type: " + value.getClass().getName());
}
}
}
}
[/code]
在上述方法中registrar.registerCustomEditors(registry);调用的是ResourceEditorRegistrar的registerCustomEditors方法,该方法代码如下:
[code="java"]
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader);
registry.registerCustomEditor(Resource.class, baseEditor);
registry.registerCustomEditor(InputStream.class, new InputStreamEditor(baseEditor));
registry.registerCustomEditor(File.class, new FileEditor(baseEditor));
registry.registerCustomEditor(URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
registry.registerCustomEditor(Class.class, new ClassEditor(classLoader));
registry.registerCustomEditor(URI.class, new URIEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver) {
registry.registerCustomEditor(Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader));
}
}
[/code]
从上面可以看出对于Resource、Resource[]类型的属性,PropertyEditor分别为ResourceEditor、ResourceArrayPropertyEditor,所以在自己定义的Test类中的属性locations、location是由上面这两个PropertyEditor解析完成的。
而ResourceEditor、ResourceArrayPropertyEditor解析真正用到的是AbstractApplicationContext中的PathMatchingResourcePatternResolver类,所以真正的解析类是PathMatchingResourcePatternResolver