阅读后发现有些地方和帮助文档不符合,我用的是9.2版本,红色
在讲一些sample之前,我们来看看整个ADF的体系架构,ADF里面有大部分类是纯JAVA的。它是构建在JSF之上的,所以它严格地遵守JSF的规范,所有的Bean都放在faces-config.xml和web.xml这样的配置文件中。就讲讲这两个文件里面的配置;
Faces-config.xml文件中有如下配置:
这里定义了一个managed bean指向了WebSession的类,这个WebSession类实现了一个接口,这个接口是HttpSessionListener[color=red](帮助文档是实现的javax.servlet.http.HttpSessionBindingListener),[/color]看看这个接口的Javadoc吧;这个接口做两件事情:每当往Session中存入一个对象(setAttribute)或从Session中删除一个对象的时候,如果这个对象实现了此监听器接口,应用服务器将会自动调用接口相应的方法。你有机会在这两个方法里面做一些事情,最好的莫过于初始化存放在session中的变量。如果你一定要问我,Managed Bean的scope如果是session,那么在每个新session中,都会初始化这个managed bean,调用它的constructor,这样不是也可以实现managed bean地初始化么?如果你一定要这样写,也可以,但是系统的可扩展性很差啦。
在ADF中,如果我们写了一个类,并且希望这个类能够被ADF初始化,我们直接实现WebContextInitialize接口就可以了,ADF会自动初始化这个类,那么WebContextInitialize接口是什么呢?
首先,来看看我们的核心中的核心WebContext,ADF的广大Managed bean们都团结在WebContext里面;这个WebContext是这个Server ADF的容器。Context这个词翻译成上下文实在是不合适,我们还是叫它叫容器吧。
这个容器里面有什么?随便举个例子吧,它有很多的Attribute,比如有一个WebMap,所有容器里面的Attribute都需要实现一个接口,这个接口的名字叫做WebContextInitialize,这个伟大的接口有两个方法:init和destroy。看看这两个方法,我不说你都能想到它们是用来做什么的。初始化这个attribute,和销毁这个attribute。看个帮助里面的例子吧:
OK,这个attribute也将作为一个managed bean部署在faces-config.xml文件里面。这里引出的问题是,谁来调用这个init方法和destroy方法呢?对JSF来说,这两个只是普通的方法,JSF不会调用这两个方法来进行资源的初始化和释放。答案是WebContext来调用这些初始化和释放的方法,我们可以看WebContext的doc原文:
WebContext is responsible for making the callback methods implemented by the resources and attributes at appropriate junctures of the ADF application. The callback methods are declared in the WebContextInitialize, WebContextObserver and WebLifecycle interfaces.
原来是WebContext负责调用这三个接口的方法,初始化和释放资源。
我们看一下WebContext,发现它也是需要有人来初始化它的,那么WebContext是谁来负责的呢? 是WebSession。WebSession里面存放了所有的WebContext,并且保证这些WebContext们能够被正常的初始化和destroy,什么时候初始化,什么时候Destroy,当然由WebSession实现的,大名鼎鼎的HttpSessionBindingListener接口来实现,每次有一个用户访问或者用户退出时,该监听器会自动调用两个方法,用来初始化和摧毁WebContext。另外要说一句地时:一个session可以有多个webContext,你可以用getWebContexts()得到所有的WebContext。目前我们看到的所有的配置文件都只使用了一个WebContext,多个WebContext会使用在什么地方呢,这个问题大家先考虑一下,我在后面的讲座中会揭晓答案。
如果有多个用户访问时,就会产生多个并发用户,我们的Web Server会为每个用户都分配一个WebSession,这些Websession会放在哪里,答案是放在WebApplication中,我们打开faces-config.xml文件可以看到里面有一个webApplication的定义
再去看WebSesstion的定义,有指向esriWebApplication的引用。
现在的问题是谁,初始化了WebApplication,我们最原始也是最强大的武器了:ServletContextListener出马了,看web.xml中下面的顶定义,
ADFServletContextListener 实现ServletContextListener接口,ServletContextListener有两个方法:contextInitialized()和contextDestroyed(); 分别在web application启动的时候和结束的时候调用,你要是觉得好玩,可以写一个listener玩玩,我这里写一个简单的listener现现丑:
ESRI使用了ADFServletContextListener,它实现了ServletContextListener接口,用来启动和destroy WebApplication。看看Javadoc的原文吧:
The ADFServletContextListener initializes a WebApplication object and sets it as an attribute on the ServletContext. When the ServletContext is destroyed, it destroys the associated WebApplication and attempts to clean up all server hosted objects in the current thread.
This class must be registered as a listener-class (in the web.xml file) for the web application.
现在大家都明白了吧,整个调用过程。[color=red]Servelt容器启动的时候,会发送启动消息给ADFServletContextListener,ADFServletContextListener负责创建WebApplication,WebApplication负责创建和存放WebSession,WebSession负责创建WebContext,WebContext负责创建所有的Attribute,对资源的使用等等。[/color]这一下大家都满意了吧。
补充:
1.HttpSessionListener:监听Http会话创建、销毁的信息,只要客户端与服务器直接建立了Http会话就会被监听到,比如一个客户端访问了Web应用的首页。 sessionCreated()和sessionDestroyed()
2.HttpSessionBindingListener:只有在实现了它的对象被绑定到属性或从会话属性中解除绑定时,才会触发该对象的valueBound()和valueUnboundy()方法,适用于记录某一用户的登录、注销动作
3.ServletContextListener:应用ServletContextListener接口,可以实现在web应用程序初始化时,自动运行一些初始化程序。contextDestroyed()和contextInitialized()
在讲一些sample之前,我们来看看整个ADF的体系架构,ADF里面有大部分类是纯JAVA的。它是构建在JSF之上的,所以它严格地遵守JSF的规范,所有的Bean都放在faces-config.xml和web.xml这样的配置文件中。就讲讲这两个文件里面的配置;
Faces-config.xml文件中有如下配置:
<managed-bean>
<managed-bean-name>esriWebSession</managed-bean-name>
<managed-bean-class>com.esri.adf.web.data.WebSession</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>webApplication</property-name>
<value>#{esriWebApplication}</value>
</managed-property>
</managed-bean>
这里定义了一个managed bean指向了WebSession的类,这个WebSession类实现了一个接口,这个接口是HttpSessionListener[color=red](帮助文档是实现的javax.servlet.http.HttpSessionBindingListener),[/color]看看这个接口的Javadoc吧;这个接口做两件事情:每当往Session中存入一个对象(setAttribute)或从Session中删除一个对象的时候,如果这个对象实现了此监听器接口,应用服务器将会自动调用接口相应的方法。你有机会在这两个方法里面做一些事情,最好的莫过于初始化存放在session中的变量。如果你一定要问我,Managed Bean的scope如果是session,那么在每个新session中,都会初始化这个managed bean,调用它的constructor,这样不是也可以实现managed bean地初始化么?如果你一定要这样写,也可以,但是系统的可扩展性很差啦。
在ADF中,如果我们写了一个类,并且希望这个类能够被ADF初始化,我们直接实现WebContextInitialize接口就可以了,ADF会自动初始化这个类,那么WebContextInitialize接口是什么呢?
首先,来看看我们的核心中的核心WebContext,ADF的广大Managed bean们都团结在WebContext里面;这个WebContext是这个Server ADF的容器。Context这个词翻译成上下文实在是不合适,我们还是叫它叫容器吧。
这个容器里面有什么?随便举个例子吧,它有很多的Attribute,比如有一个WebMap,所有容器里面的Attribute都需要实现一个接口,这个接口的名字叫做WebContextInitialize,这个伟大的接口有两个方法:init和destroy。看看这两个方法,我不说你都能想到它们是用来做什么的。初始化这个attribute,和销毁这个attribute。看个帮助里面的例子吧:
public class MyAttribute implements WebContextInitialize {
WebContext context;
public void init(WebContext context) {
this.context = context;
//初始化其它资源或者变量
}
public void destroy() {
context = null;
//释放其它资源
}
}
OK,这个attribute也将作为一个managed bean部署在faces-config.xml文件里面。这里引出的问题是,谁来调用这个init方法和destroy方法呢?对JSF来说,这两个只是普通的方法,JSF不会调用这两个方法来进行资源的初始化和释放。答案是WebContext来调用这些初始化和释放的方法,我们可以看WebContext的doc原文:
WebContext is responsible for making the callback methods implemented by the resources and attributes at appropriate junctures of the ADF application. The callback methods are declared in the WebContextInitialize, WebContextObserver and WebLifecycle interfaces.
原来是WebContext负责调用这三个接口的方法,初始化和释放资源。
我们看一下WebContext,发现它也是需要有人来初始化它的,那么WebContext是谁来负责的呢? 是WebSession。WebSession里面存放了所有的WebContext,并且保证这些WebContext们能够被正常的初始化和destroy,什么时候初始化,什么时候Destroy,当然由WebSession实现的,大名鼎鼎的HttpSessionBindingListener接口来实现,每次有一个用户访问或者用户退出时,该监听器会自动调用两个方法,用来初始化和摧毁WebContext。另外要说一句地时:一个session可以有多个webContext,你可以用getWebContexts()得到所有的WebContext。目前我们看到的所有的配置文件都只使用了一个WebContext,多个WebContext会使用在什么地方呢,这个问题大家先考虑一下,我在后面的讲座中会揭晓答案。
如果有多个用户访问时,就会产生多个并发用户,我们的Web Server会为每个用户都分配一个WebSession,这些Websession会放在哪里,答案是放在WebApplication中,我们打开faces-config.xml文件可以看到里面有一个webApplication的定义
<referenced-bean>
<referenced-bean-name>esriWebApplication</referenced-bean-name>
<referenced-bean-class>com.esri.adf.web.data.WebApplication</referenced-bean-class>
</referenced-bean>
再去看WebSesstion的定义,有指向esriWebApplication的引用。
现在的问题是谁,初始化了WebApplication,我们最原始也是最强大的武器了:ServletContextListener出马了,看web.xml中下面的顶定义,
<listener>
<listener-class>com.esri.adf.web.util.ADFServletContextListener</listener-class>
</listener>
ADFServletContextListener 实现ServletContextListener接口,ServletContextListener有两个方法:contextInitialized()和contextDestroyed(); 分别在web application启动的时候和结束的时候调用,你要是觉得好玩,可以写一个listener玩玩,我这里写一个简单的listener现现丑:
public class ScheduleListener implements ServletContextListener {
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("context object inited.");
}
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("context object destroyed.");
}
}
ESRI使用了ADFServletContextListener,它实现了ServletContextListener接口,用来启动和destroy WebApplication。看看Javadoc的原文吧:
The ADFServletContextListener initializes a WebApplication object and sets it as an attribute on the ServletContext. When the ServletContext is destroyed, it destroys the associated WebApplication and attempts to clean up all server hosted objects in the current thread.
This class must be registered as a listener-class (in the web.xml file) for the web application.
现在大家都明白了吧,整个调用过程。[color=red]Servelt容器启动的时候,会发送启动消息给ADFServletContextListener,ADFServletContextListener负责创建WebApplication,WebApplication负责创建和存放WebSession,WebSession负责创建WebContext,WebContext负责创建所有的Attribute,对资源的使用等等。[/color]这一下大家都满意了吧。
补充:
1.HttpSessionListener:监听Http会话创建、销毁的信息,只要客户端与服务器直接建立了Http会话就会被监听到,比如一个客户端访问了Web应用的首页。 sessionCreated()和sessionDestroyed()
2.HttpSessionBindingListener:只有在实现了它的对象被绑定到属性或从会话属性中解除绑定时,才会触发该对象的valueBound()和valueUnboundy()方法,适用于记录某一用户的登录、注销动作
3.ServletContextListener:应用ServletContextListener接口,可以实现在web应用程序初始化时,自动运行一些初始化程序。contextDestroyed()和contextInitialized()