我正在使用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中操作此文件?
答案 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();
}
}
}