cgttian 2011-03-22 23:15 采纳率: 100%
浏览 337
已采纳

Spring 中对于如classpath: 这类的解析在哪里进行?

今天遇到一个问题,在Spring中声明的自定义Bean中需要注入 一个配置文件 xxx.xml,想用 SpringBean中配置文件注入的方式如:classpath:xxx-ibatis.xml.

查看了spring 对 ibatis 支持中的 SqlMapClientFactoryBean,发现其configLocation 属性其实是个Resource 接口,尝试直接实例化了实现Resource接口的 ClassPathResource、FileSystemResource 等都无法取得正确的文件路径.

那Spring 对 classpath: 的解析在哪里进行?
在spring 配置文件中对SqlMapClientFactoryBean configLocation 属赋的值又是组装成哪个Resource实现类传入?

仅有的 5 分 求解!!! :cry:

:o 以哪个Resource实现类传入 会不会跟 启动了哪个 ApplicationContext 有关...

  • 写回答

2条回答 默认 最新

  • piaoyao1203 2011-03-23 12:36
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 iOS 自定义输入法-第三方输入法
  • ¥15 很想要一个很好的答案或提示
  • ¥15 扫描项目中发现AndroidOS.Agent、Android/SmsThief.LI!tr
  • ¥15 怀疑手机被监控,请问怎么解决和防止
  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区
  • ¥15 在grasshopper里DrawViewportWires更改预览后,禁用电池仍然显示
  • ¥15 NAO机器人的录音程序保存问题
  • ¥15 C#读写EXCEL文件,不同编译