Seam学习(一) 下上文context
Seam学习(一) 上下文context
1. 首先,谈谈JSF中作用域存在的缺点,标准JSF的Managed Bean,必须通过XML进行配置,过于麻烦;贫乏的作用域,上文提及标准的JSF的Managed Bean只有四种作用域:none、request、session和application。由于JSF对状态的依赖比较强,经常需要在请求之间保存应用的状态,所以很多时候我们时候都不得不使用Session作用域的Managed Bean。但是众所周知,过多地使用Session会带来很多问题,如容易造成内存耗尽,难于集群(Cluster)等。
2. 因此,Seam对JSF进行了扩展,并进而起草了Web Bean标准(Web Bean还在BETA阶段,坦白的说我也不是很了解)。下面我们就来学习一下Seam的Managed Bean(官方文档中叫Component)。在这方面Seam与标准JSF有如下不同:
(1).Seam的Component既可以通过XML配置,又可以通过Annotation的方式配置。我个人比较偏爱Annotation的方式,方便快捷,能够提高工作效率。XML方式有一个好处就是可以集中管理,但是因为Managed Bean配置相对比较稳定,不会经常修改,所以XML优势并不会太明显;
(2).更丰富的作用域(Seam中称为上下文Context),Seam有6种上下文可选:无状态(Stateless Context)、事件(Event Context,或者Request Context)、页面(Page Context)、对话(Conversation Context)、会话(Session Context)、业务流(Business Process Context)和应用程序(Application Context);
(3).Seam引入一种双向注入(Binjection)的方式。所谓的双向注入就是可以将上下文中的Bean注入到另一个Bean中,又或者将Bean中的属性(Property)直接发布在上下文中;
3.seam中component的定义与使用.
(1).一个简单的Component的定义的例子:
package net.blogjava.max.hello.session;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@Name("helloWB")
@Scope(ScopeType.PAGE)
public class HelloWB {
private String name;
private String message;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void sayHello() {
message = "Hello, " + name + "!";
}
public void anotherEvent() {
System.out.println("Another request is coming");
}
}
通过上述代码,大家可以看到有两句Annotation定义——Name和Scope.除此之外,并没有什么特别的地方,所以正是这两个Annotation使HelloWB成为一个可以被SEAM的运行时识别的Component.Name用于定义Component的名称,@Name(value),value必须是本类类名小写的形式,;Scope则用于定义Component的作用域,是可选的,默认值为短对话(Short Conversation)。在本例中,HelloWB的作用域是Page.Page与Conversation都Seam的杰作,在标准JSF是没有的。而且,这两个作用域是比较常用,我个人比较热衷于Page作用域,所以在这里先谈一下Page.
正如我前面所说“JSF对状态的依赖比较强……”,造成我们对Session的依赖,引起了很多问题。Page很大程度上解决了这个问题,它可以跨请求存活,只要该请求不是“新的”。什么请求是“新的”请求呢?要回答这个问题,先要搞清楚什么是“POST-BACK”。学过ASP.NET的朋友可能对POST-BACK概念比较熟悉,没学过的话不要紧。POST-BACK并不是什么深奥的东西,所谓的POST-BACK,就是指用户按下页面上的某个按钮或表单控件,将表单数据发送回到页面自身的URL.相反,如果用户是通过在地址栏中输入URL,或通过点击页面的链接访问页面,则这个请求就是一个NON-POST-BACK的请求,也即是一个新的请求。
另外,一些JSF专家都推荐一种叫Backing Bean的风格。所谓的Backing Bean就是指一个JSF页面对应一个Managed Bean处理页面逻辑。Page作用域非常适用这种情况,因为它是与页面一起序列化(Serialize)到浏览器或保存在Session中。如果大家还是不太明白的话,请看以下的XHTML代码.
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
5 <head>
6 <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
7 <title>
8 Hello World
9 </title>
10 </head>
11 <body>
12 <h:form>
13 <h:outputLabel value="Name: " for="itName" />
14 <h:inputText id="itName" value="#{helloWB.name}" />
15 <h:commandButton action="#{helloWB.sayHello}" value="Say Hello" />
16 <h:commandButton action="#{helloWB.anotherEvent}" value="Another Reqeust" />
17 <hr />
18 <h2>
19 <h:outputText value="#{helloWB.message}" />
20 </h2>
21 </h:form>
22 </body>
23 </html>
1. 首先,谈谈JSF中作用域存在的缺点,标准JSF的Managed Bean,必须通过XML进行配置,过于麻烦;贫乏的作用域,上文提及标准的JSF的Managed Bean只有四种作用域:none、request、session和application。由于JSF对状态的依赖比较强,经常需要在请求之间保存应用的状态,所以很多时候我们时候都不得不使用Session作用域的Managed Bean。但是众所周知,过多地使用Session会带来很多问题,如容易造成内存耗尽,难于集群(Cluster)等。
2. 因此,Seam对JSF进行了扩展,并进而起草了Web Bean标准(Web Bean还在BETA阶段,坦白的说我也不是很了解)。下面我们就来学习一下Seam的Managed Bean(官方文档中叫Component)。在这方面Seam与标准JSF有如下不同:
(1).Seam的Component既可以通过XML配置,又可以通过Annotation的方式配置。我个人比较偏爱Annotation的方式,方便快捷,能够提高工作效率。XML方式有一个好处就是可以集中管理,但是因为Managed Bean配置相对比较稳定,不会经常修改,所以XML优势并不会太明显;
(2).更丰富的作用域(Seam中称为上下文Context),Seam有6种上下文可选:无状态(Stateless Context)、事件(Event Context,或者Request Context)、页面(Page Context)、对话(Conversation Context)、会话(Session Context)、业务流(Business Process Context)和应用程序(Application Context);
(3).Seam引入一种双向注入(Binjection)的方式。所谓的双向注入就是可以将上下文中的Bean注入到另一个Bean中,又或者将Bean中的属性(Property)直接发布在上下文中;
3.seam中component的定义与使用.
(1).一个简单的Component的定义的例子:
package net.blogjava.max.hello.session;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@Name("helloWB")
@Scope(ScopeType.PAGE)
public class HelloWB {
private String name;
private String message;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public void sayHello() {
message = "Hello, " + name + "!";
}
public void anotherEvent() {
System.out.println("Another request is coming");
}
}
通过上述代码,大家可以看到有两句Annotation定义——Name和Scope.除此之外,并没有什么特别的地方,所以正是这两个Annotation使HelloWB成为一个可以被SEAM的运行时识别的Component.Name用于定义Component的名称,@Name(value),value必须是本类类名小写的形式,;Scope则用于定义Component的作用域,是可选的,默认值为短对话(Short Conversation)。在本例中,HelloWB的作用域是Page.Page与Conversation都Seam的杰作,在标准JSF是没有的。而且,这两个作用域是比较常用,我个人比较热衷于Page作用域,所以在这里先谈一下Page.
正如我前面所说“JSF对状态的依赖比较强……”,造成我们对Session的依赖,引起了很多问题。Page很大程度上解决了这个问题,它可以跨请求存活,只要该请求不是“新的”。什么请求是“新的”请求呢?要回答这个问题,先要搞清楚什么是“POST-BACK”。学过ASP.NET的朋友可能对POST-BACK概念比较熟悉,没学过的话不要紧。POST-BACK并不是什么深奥的东西,所谓的POST-BACK,就是指用户按下页面上的某个按钮或表单控件,将表单数据发送回到页面自身的URL.相反,如果用户是通过在地址栏中输入URL,或通过点击页面的链接访问页面,则这个请求就是一个NON-POST-BACK的请求,也即是一个新的请求。
另外,一些JSF专家都推荐一种叫Backing Bean的风格。所谓的Backing Bean就是指一个JSF页面对应一个Managed Bean处理页面逻辑。Page作用域非常适用这种情况,因为它是与页面一起序列化(Serialize)到浏览器或保存在Session中。如果大家还是不太明白的话,请看以下的XHTML代码.
1 <?xml version="1.0" encoding="utf-8"?>
2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3
4 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">
5 <head>
6 <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
7 <title>
8 Hello World
9 </title>
10 </head>
11 <body>
12 <h:form>
13 <h:outputLabel value="Name: " for="itName" />
14 <h:inputText id="itName" value="#{helloWB.name}" />
15 <h:commandButton action="#{helloWB.sayHello}" value="Say Hello" />
16 <h:commandButton action="#{helloWB.anotherEvent}" value="Another Reqeust" />
17 <hr />
18 <h2>
19 <h:outputText value="#{helloWB.message}" />
20 </h2>
21 </h:form>
22 </body>
23 </html>