是否有任何内置线程在Spring中操作DefaultNamespaceHandlerResolver?

时间:2014-12-15 06:13:44

标签: java multithreading spring

我正在使用Spring调试应用程序。当我进入DefaultNamespaceHandlerResolver中的下面的构造函数时,我发现了一些奇怪的东西,它由XmlBeanDefinitionReader调用。 createReaderContext(资源资源):

public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) {
        Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
        this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
        this.handlerMappingsLocation = handlerMappingsLocation;
    }

在DefaultNamespaceHandlerResolver中有一个名为handlerMappings的字段,如下所示:

private volatile Map<String, Object> handlerMappings;

在我运行上面的构造函数之后,这个字段的值将被更改,但是,我无法找到其值如何变化的线索,因为在上面的construtor中只设置了classloader和handlerMappingLocation。  我注意到handlerMappings已声明为volatile。所以我的问题是,是否有任何内置线程或其他线程在Spring中操作此文件?

1 个答案:

答案 0 :(得分:0)

另外,这让我感到困惑,我认为这是 没有 内置线程或其他线程在Spring中操作这个字段。

我发现有以下toString()方法(here)将执行getHandlerMappings()方法。

@Override
public String toString() {
    return "NamespaceHandlerResolver using mappings " + getHandlerMappings();
}

当我们在IntelliJ或Eclipse中调试时,我认为IDE将在另一个线程中执行toString()方法以显示对象的人类可读值。

这是测试代码:

public class ToStringTest {

    public static void main(String[] args) {

        WilltoStringInvoked will = new WilltoStringInvoked();

        // #breakpoint1
        System.out.println("If breakpoint here value will be 1");

        /**
         * If we set an breakpoint before this method the output will 
         * be 1, otherwise the output will be 0
         */
        System.out.println(will.getValue());

        // #breakpoint2
        System.out.println("If breakpoint here value will be 0");
    }

    static class WilltoStringInvoked {

        private volatile  int value = 0;

        private int setValue() {
           if (value == 0) {
               synchronized (this) {
                   if (value == 0) {
                       value = 1;
                   }
               }
           }

           return value;
        }

        public int getValue() {
            return value;
        }

        @Override
        public String toString() {
            return "This value is: " + setValue();
        }
    }
}