应用程序 Servlet 实际上如何管理上下文变量?
How actually applicationServlet manages context varibles?
applicationServlet 实际上是如何管理上下文变量的?如果我在 applicationContext 级别设置变量,无论它存储在 Method area 还是 stack area 或 heap ,
如果是,它是如何存储的以及如何访问的?
这里我创建了局部变量作为 MAP 并将一些值放在 applicationContext 级别。
我在下面写了一些示例代码。
public class ContextLoaderListener implements ServletContextListener {
private ServletContext ctx;
private WebApplicationContext springContext;
@Override
public void contextInitialized(ServletContextEvent sce) {
Map<String, String> resourceMap=new HashMap<>();
resourceMap.put("1","abc1");
resourceMap.put("2","abc2");
resourceMap.put("3","abc3");
sce.getServletContext().setAttribute("resourceMap", resourceMap);
}
@Override
public void contextDestroyed(ServletContextEvent sce) { }
}
我将在这里回答您的评论,我认为它也回答了您的问题。
您在评论中的问题如下:
resourceMap is local map to this partcular method. after completing
execution of this method resourceMap local variable is going to
destroy. if so then how resourceMap context variable refer to local
variable resourceMap ?
嗯,资源图只是一个局部参考。堆中的对象本身。方法执行完成后 resourceMap 丢失是对的。但是,您正在将引用的副本传递给另一个寿命更长的对象。请参阅以下示例:
class TestClass {
public static void main(String[] args) {
final ServletContext servletContext = new ServletContext();
final ServletContextEvent servletContextEvent = new ServletContextEvent(servletContext);
final ServletContextListener servletContextListener = new ServletContextListener();
servletContextListener.contextInitialized(servletContextEvent);
final Object resourceMap = servletContext.getMap().get("resourceMap");
// See, resourceMap is still accesiable. Because it still has an alive reference to it from ServletContext!
System.out.println(resourceMap);
// Output will be:
// {1=abc1}
}
}
class ServletContext {
final Map<String, Object> map = new HashMap<String, Object>();
public void setAttribute(String resourceMap, Map<String, String> value) {
this.map.put(resourceMap, value);
}
public Map<String, Object> getMap() {
return map;
}
}
class ServletContextEvent {
private final ServletContext servletContext;
public ServletContextEvent(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
}
class ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Map<String, String> resourceMap = new HashMap<String, String>();
resourceMap.put("1", "abc1");
sce.getServletContext().setAttribute("resourceMap", resourceMap);
}
}
这是否回答了您的问题?
applicationServlet 实际上是如何管理上下文变量的?如果我在 applicationContext 级别设置变量,无论它存储在 Method area 还是 stack area 或 heap , 如果是,它是如何存储的以及如何访问的?
这里我创建了局部变量作为 MAP 并将一些值放在 applicationContext 级别。
我在下面写了一些示例代码。
public class ContextLoaderListener implements ServletContextListener {
private ServletContext ctx;
private WebApplicationContext springContext;
@Override
public void contextInitialized(ServletContextEvent sce) {
Map<String, String> resourceMap=new HashMap<>();
resourceMap.put("1","abc1");
resourceMap.put("2","abc2");
resourceMap.put("3","abc3");
sce.getServletContext().setAttribute("resourceMap", resourceMap);
}
@Override
public void contextDestroyed(ServletContextEvent sce) { }
}
我将在这里回答您的评论,我认为它也回答了您的问题。
您在评论中的问题如下:
resourceMap is local map to this partcular method. after completing execution of this method resourceMap local variable is going to destroy. if so then how resourceMap context variable refer to local variable resourceMap ?
嗯,资源图只是一个局部参考。堆中的对象本身。方法执行完成后 resourceMap 丢失是对的。但是,您正在将引用的副本传递给另一个寿命更长的对象。请参阅以下示例:
class TestClass {
public static void main(String[] args) {
final ServletContext servletContext = new ServletContext();
final ServletContextEvent servletContextEvent = new ServletContextEvent(servletContext);
final ServletContextListener servletContextListener = new ServletContextListener();
servletContextListener.contextInitialized(servletContextEvent);
final Object resourceMap = servletContext.getMap().get("resourceMap");
// See, resourceMap is still accesiable. Because it still has an alive reference to it from ServletContext!
System.out.println(resourceMap);
// Output will be:
// {1=abc1}
}
}
class ServletContext {
final Map<String, Object> map = new HashMap<String, Object>();
public void setAttribute(String resourceMap, Map<String, String> value) {
this.map.put(resourceMap, value);
}
public Map<String, Object> getMap() {
return map;
}
}
class ServletContextEvent {
private final ServletContext servletContext;
public ServletContextEvent(ServletContext servletContext) {
this.servletContext = servletContext;
}
public ServletContext getServletContext() {
return servletContext;
}
}
class ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
Map<String, String> resourceMap = new HashMap<String, String>();
resourceMap.put("1", "abc1");
sce.getServletContext().setAttribute("resourceMap", resourceMap);
}
}
这是否回答了您的问题?