JSF 2.0 بصورت پیش فرض دارای 6 ناحیه حافظه ایست که اصطلاحا به آنها Scope گفته میشود, که در زیر به معرفی آنها خواهیم پرداخت :

  • RequestScoped@

کلاس Bean تعریف شده در این ناحیه حافظه با اجرای یک درخواست HTTP ایجاد و هنگامی که نتیجه اجرای درخواست به کاربر ارسال شده و در مرورگر نمایش داده شد، از بین میرود(طول عمر کلاس های Bean در درخواست هایی که بصورت Ajax ارسال میشوند نیز به همین صورت میباشد). کتابخانه JSF برای دسترسی به کلاسهای Bean تعریف شده در این مدل حافظه ای از دو روش استفاده میکند :

  1. روش اول استفاده از آبجکت HttpServletRequest میباشد. در این حالت نام کلاس Bean به عنوان کلید در آبجکت HttpServletRequest در نظر گرفته میشود.

  2. روش دوم استفاده از آبجکت ExternalContext#getRequestMap میباشد.

از این Scope بهتر است در صفحاتی استفاده شود که از Ajax استفاده نکرده و نیازی به نگهداری مقادیر در درخواست های متوالی ارسال شده از سوی کاربر ندارند.

  • ViewScoped@

کلاسهای تعریف شده در این مدل حافظه ای تا زمانی که صفحه JSF در پنجره مرورگر و یا یکی از Tab ها باز بوده, قابل دسترس میباشند. این Scope با ارسال یک Request از سوی کاربر ایجاد شده و تا زمانی که کاربر به صفحه ی دیگری نرود، در حافظه سرور باقی خواهد ماند(با جابجایی بین صفحات یک Instance جدید از کلاس ایجاد شده و نمونه های قبلی از بین خواهد رفت). کتابخانه JSF مقادیر ذخیره شده در کلاسهای این نوع حافظه را در آبجکتی بنام UIViewRoot#getViewMaبا نام کلاس Bean ذخیره میکند.

برای اینکه داده ها و مقادیر این نوع Scope در طول مدت اجرای یک صفحه JSF در حافظه سرور باقی بمانند باید خروجی متدهای کلاس از نوع void یا Null باشد.

این Scope بهترین مدل حافظه ای برای استفاده از صفحات Ajax، صفحاتی که دارای DataTable میباشند، صفحاتی که طبق شرایط برخی از کامپوننت های آنرا میخواهید rendered نمائید و ... میباشد.

 

نکته: صفحه ای شامل یک DataTable با Paginator (DataTable بصورت page به Page در صفحه تعریف شده است) در نظر بگیرید. اگر این صفحه را در ناحیه RequestScope@ مورد استفاده قرار دهید، در هر باری که کاربر وارد یکی از صفحات DataTable شده و یا بین آنها جابجا گردد، یک Request جدید به سرور رفته، صفحه Refresh شده و اطلاعات دوباره ازDatabase خوانده میشود. در ناحیه ViewScoped@ هیچکدام از این کارها انجام نشده و اطلاعات DataTable فقط یکبار در ابتدای اجرای صفحه از پایگاه داده خوانده شده و سپس نمایش داده میشود.

 

  • SessionScoped@

کلاسهای تعریف شده در این مدل حافظه ای در آبجکت Http Session مرورگر نگهداری می شوند. مقادیر این کلاسها با اجرای اولین درخواست کاربر و نگهداری آنها در Session ایجاد و تا زمانی که Session مورد نظر از بین نرفته و یا به اصطلاح invalidate نگردد در حافظه باقی خواهد ماند. کتابخانه JSF اطلاعات این نوع مدل حافظه را در آبجکت HttpSession با استفاده از نام کلاس Bean، نگهداری میکند

(روش دیگر استفاده از ExternalContext#getSessionMap میباشد). از این Scope بهتر است زمانی استفاده گردد که میخواهید اطلاعاتی خاص بین تمام پنجره ها و Tab های مرورگر جابجا گردد.

به عنوان مثال بهتر است اطلاعات کاربر، شامل نام و نام خانوادگی کاربران وب سایت خود را در این Scope نگهداری نمائید.

 

  • ApplicationScoped@

کلاسهای تعریف شده در این Scope تا زمانی که برنامه Web بر روی سرور در حال اجرا میباشد، در حافظه ی سرور باقی خواهد ماند. این مدل حافظه با اجرای اولین درخواست کاربر ایجاد و تا زمانی که برنامه وب از روی سرور Shutdown نگردد، باقی خواهد ماند.

(روش دیگر مقداردهی این کلاس نیز استفاده از خاصیت eagar = true در کلاسهای ManagedBean@ میباشد. کلاسهایی که دارای این خاصیت میباشند، بصورت اتوماتیک به حافظه ApplicationScope انتقال داده میشوند).

کتابخانه JSF مقادیر ذخیره شده در این کلاسهای در دو آبجکت ServletContext و یا ExternalContext#getApplication با نام کلاس Bean ذخیره میکند.

از این مدل حافظه بهتر است زمانی استفاده گردد که میخواهید یک مقدار خاص بین تمام Session های شما به اشتراک گذاشته شود. همچنین میتوانید مقادیر ثابت کمبوباکس ها را نیز در این مدل حافظه ای قرار دهید.

  • NoneScoped@

کلاس Bean تعریف شده در این مدل حافظه تنها در طول اجرای یک درخواست EL در حافظه سرور باقی میماند. با اتمام درخواست، Instance کلاس نیز از بین خواهد رفت. کتابخانه JSF اطلاعات و مقادیر کلاس را در هیچ جایی نگهداری نمیکند.

به این نکته توجه داشته باشید که اگر JSF View شما دارای سه دستور بصورت #{bean.someProperty} باشد، کلاس Bean سه بار در طول اجرای صفحه ایجاد میگردد.

  • CustomeScoped@

نگهداری و مدیریت کلاسهای Bean در این مدل حافظه ای کاملا بر عهده برنامه نویس باشد. و برنامه نویس وظیفه مدیریت آبجکت ها را بر عهده دارد. از این مدل حافظه ای بهتر است زمانی استفاده گردد که هیچکدام از Scope ها متناسب با نیاز شما نباشد.

 

نکات و نتیجه گیری :

  • از ApplicationScoped هنگامی استفاده نمایید که بخواهید داده های خود را بین سایر Scope های (Session/view/request) به اشتراک بگذارید.
  • از SessionScoped هنگامی استفاده نمایید که بخواهید برخی از داده های خود را بین ViewScoped/RequestScoped در پنجره مرورگر و یا بین Tab های آن به اشتراک بگذارید. 
  • اگر یک کلاس Bean تعریف کرده اید که شامل داده هایی در Scope های Request و Session میباشد بهتر است داده های خود را جدا کرده وهر کدام را در دو کلاس جداگانه تعریف نموده و سپس با استفاده از ManagedProperty@ آنها را در یک کلاس Bean دیگر Inject نمایید.
  • اگر از Ajax در صفحات برنامه خود استفاده میکنید, بهتر مدل حافظه ای, ٰViewScoped@ میباشد.
  • اگر میخواهید اطلاعات کاربران (از قیبل نام و نام خانوادگی و...) را در تمامی صفحات JSF نمایش دهید, آنها را در SessionScoped@ نگهداری نمایید.
  • بهترین مدل حافظه ای در صفحاتی که از Ajax استفاده نمیکنند, RequestScoped@ میباشد.
  • اگر از  ViewScoped@ استفاده میکنید, کلاسهای Bean باید با استفاده از دستور implements Serializable پیاده سازی شوند.