JSF教程(2)——ManageBean中的Scope

上一篇文件中介绍了JSFHelloWorld,其中在ManagedBean中我们比较敏感的信息是关于Scope的注解,在Struts中配置一个Action的时候也是需要配置Scope的,他们有些相似,只不过此Scope非彼Scope。如果读者对Struts比较了解那么对于Scope肯定有自己的理解,其实Scope(范围)就是在形容这个被描述的物体所存在的范围。Java官方的Tutorial中是这样描述的。

You can use annotations to define the scope in which the bean will be stored. Youcan specify one of the following scopes for a bean class:

Application(@ApplicationScoped): Application scope persists across all users’ interactionswith a web application.

Session(@SessionScoped): Session scope persists across multiple HTTP requests in a webapplication.

View(@ViewScoped): View scope persists during a user’s interaction with a singlepage (view) of a web application.

Request(@RequestScoped): Request scope persists during a single HTTP request in a webapplication.

None(@NoneScoped): Indicates a scope is not defined for the application.

Custom(@CustomScoped): A user-defined, nonstandard scope. Its value must beconfigured as a java.util.Map. Custom scopes are used infrequently.

请注意以上出自JavaEE6 Tutorial文档.

关于开发中的版本

也许对于开发人员来说最郁闷的事情莫过于你熟悉了一个技术之后发现这个技术居然不流行了,或者这项技术已经更新换代了,比这更令人郁闷的是新老版本不兼容,或者新版本从根本上否定了旧的版本。比如Struts1Struts2比如Jbpm4Jbpm5比如primeface3primeface4类似的例子还有很多。笔者的观点是这些问题对于刚入行的新手而言是致命的,但是对于老鸟来说是无所谓的,因为就像金庸武侠小说里说的“无招胜有招”只要你掌握了学习的方法,掌握了如何对待新知识的方法哪个版本对你来说都是一样的。从另一方面来说也正是IT领域更新换代的速度才筛选出了优秀的开发者。

为了进一步理解scope的含义,我们对上一篇博客中的HelloBean使用不同的注解,然后建立对应的页面进行测试。在每个页面进行提交的时候都将一个变量自动增加,在另一个页面观察其提交的次数。以ApplicationScoped为例代码如下:

package com.xxy.common;

import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.io.Serializable;

@ManagedBean
@ApplicationScoped
public class HelloBeanForApplicationScoped implements Serializable {

    public int commitTimes =0;
    private String name;

    public String doSomething(){
        commitTimes++;
        return "welcomeForApplicationScoped";
    }

    public int getCommitTimes() {
        return commitTimes;
    }

    public void setCommitTimes(int commitTimes) {
        this.commitTimes = commitTimes;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

一、ApplicationScoped,就是在整个应用级别存储对应Bean的信息。这时在不同的浏览器中,甚至于局域网内不同的电脑当中打开helloForApplicationScope.xhtml所对应的页面。在一个浏览器(或者电脑A)中提交表单之后显示提交的次数是1次,在另一个浏览器(或者电脑B)当中再次提交表单显示提交的次数是2次。这就说明了使用ApplicationScoped注解是将此Bean存储在了系统级别,虽然是不同的环境只要需要访问这个Bean就会收到任何之前任何一次提交的影响,无论上次提交是相同的环境还是不同的。有些类似于单例模式,整个系统中只实例化一次。

二、SessionScoped顾名思义就是在Session级别保存这个Bean中的内容。

关于Session

很多国内的翻译中Session的意思都被译作“会话”其实笔者觉得翻译的有些不尽人意,理解计算机中的术语最好的办法就是查这个单词的意思然后忘记中文的翻译。Session在词典中的解释是“会议”或者“法庭的开庭”或者是“学期”。那么这三个词有一个共同的特点就是有时间段限制,而且各个时间段内发生的事情是相互独立的。举个例子就是法庭在审理案件的时候不会考虑上个案件中发生的事情,而且一审的结果出来之后就已经定了,想要改变结果只能通过二审(相当于计算机中的两个Session);这个学期所取得成绩和上个学期没有直接的关系,第一学期没有考好没有拿到奖学金,想要得奖学金只能等下一个学期(两个Session)因为这一学期已经结束了(Session关闭了)。

为了验证SessionScope我们可以在同一个浏览器中打开两个helloForSessionScoped.xhtml所对应的页面,然后在其中一个页面提交表单,然后在另一个页面中也提交表单,这时发现在同一个Session中的数据是相互影响的。然后等待此Session过期之后再次刷新欢迎页面发现页面数据丢失(页面报错)重新回到helloForSessionScoped.xhtml所对应的页面进行表单提交发现之前Bean中存储的信息已经丢失,提交次数重新变为一次。

三、ViewScoped在这里一个View就是指展现在用户面前的一个页面,只要用户在这个View当中那么对应的manage bean中的数据就是可以被保存的。在helloForViewScoped.xhtml所对应的页面中有三个按钮,分别是提交到其他页面,提交到本页面,不进行提交。只要最后一个不进行提交的按钮才会保存用户的数据,这也就说明了对于View而言指的是用户所面对的页面,而不是后台所对应的xhtml文件。只要用户进行提交表单那么View就更新了。

四、RequestScoped就是在每次请求服务器过程中会保存输入值,点击helloForRequestScoped.xhtml页面对应的提交按钮我们发现新页面当中的提交次数永远是1,也就是说RequestScoped的范围就是在从请求开始到请求结束,如果再次请求那么数据将被更新。

五、NoneScoped就是任何情况下都不存储manage bean中的数据,至于最后一种CustomScoped由于文档中说基本上不怎么使用我们就可以忽略了。

常见的scope已经介绍完了,有兴趣的童鞋可以看一下JavaEE7 Tutorial,你会发现在新版的JavaEEscope发生了一些小变化,只要理解了scope应对这些变化还是没啥问题的。下面要说的是猜测JSF是如何做到将数据存储到Manage Bean中的?

如果我来实现我的做法应该是这样:首先既然Manage Bean是一个POJO而且是由容器托管的,所以应该在容器启动的时候会通过反射实例化Bean,在请求的时候根据不同的Scope注解选择是将此Bean重新实例化或者继续使用已有的对象(每次请求中的信息就是是否重新实例化Manage Bean的决定条件)。如果使用已有的对象那么给用户的感觉就像是将数据存储了起来,反之就是没有存储数据。

想法有了接下来要做的就是去看源码了,有兴趣的同学可以去下载JSF源码验证一下自己的想法是否和JSF实现者想法一致。


本教程项目源码gitHub 地址(所有源码均来自于网络,随着教程的继续源码会持续更新,欢迎交流)。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值