cgttian 2011-03-22 15: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 04: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 传人记程序做的plc 485从机程序该如何写
  • ¥15 已知手指抓握过程中掌指关节、手指各关节和指尖每一帧的坐标,用贝塞尔曲线可以拟合手指抓握的运动轨迹吗?
  • ¥50 libwebsockets 如何添加其他socket事件回调
  • ¥50 实现画布拖拽算子排布,通过flink实现算子编排计算,请提供思路
  • ¥15 esium自定义材质拉伸问题
  • ¥15 cmake+mingw使用<mysqlx/xdevapi.h>报错
  • ¥15 eNSP中防火墙的使用
  • ¥15 关于#mlnet#的问题:mlnet相关请求(语言-c#)
  • ¥15 lvgl7.11怎么做出文字被选中的效果
  • ¥50 如何快速查看手机目标app的主要服务器ip
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部