7. مثال برنامه کاربردی-04: rdvmedecins-pf-spring
7.1. پورت کردن
ما اکنون در حال انتقال برنامه قبلی به محیط Spring/Tomcat هستیم:
![]() |
ما بر روی دو برنامهای که قبلاً نوشته شدهاند، توسعه خواهیم داد. ما از موارد زیر استفاده خواهیم کرد:
- لایههای [DAO] و [JPA] از نسخه 02 JSF / Spring،
- لایه [web] / PrimeFaces از نسخه 03 (PF / EJB)،
- فایلهای پیکربندی Spring از نسخه 02
ما در اینجا در حال تکرار فرایندی مشابه با آنچه برای انتقال برنامه JSF2 / EJB / GlassFish به یک محیط JSF2 / Spring Tomcat انجام شد، هستیم. بنابراین توضیحات کمتری ارائه خواهیم داد. در صورت لزوم، خواننده میتواند به آن پورت مراجعه کند.
ما تمام پروژههای مورد نیاز برای انتقال را در یک پوشه جدید به نام [rdvmedecins-pf-spring] [1] قرار میدهیم:
![]() |
- [mv-rdvmedecins-spring-dao-jpa]: لایههای [DAO] و [JPA] از نسخه 02 JSF / Spring،
- [mv-rdvmedecins-spring-metier]: لایه [métier] از نسخه 02 JSF / Spring,
- [mv-rdvmedecins-pf]: لایه [web] از نسخه 03 PrimeFaces / EJB،
- به [2]، ما آنها را در NetBeans بارگذاری میکنیم،
- در [3]، وابستگیهای پروژه وب دیگر درست نیستند:
- وابستگیها به لایههای [DAO]، [JPA] و [métier] باید تغییر کنند تا اکنون پروژههای Spring را هدف قرار دهند؛
- سرور GlassFish کتابخانهها را برای JSF فراهم میکرد. این وضعیت دیگر با سرور Tomcat صادق نیست. بنابراین باید آنها به وابستگیها اضافه شوند.
پروژه [web] به شرح زیر تغییر کرده است:
![]() |
فایل [pom.xml] در لایه [web] اکنون وابستگیهای زیر را دارد:
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mv-rdvmedecins-spring-metier</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-api</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>com.sun.faces</groupId>
<artifactId>jsf-impl</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>3.3</version>
</dependency>
</dependencies>
خطاهایی رخ میدهند. این خطاها ناشی از ارجاعات به EJB در لایه [web] هستند. ابتدا بیان [Application] را بررسی کنیم:
![]() |
ما تمام خطوطی را که به دلیل وجود پکیجهای ناقص خطا ایجاد میکنند، حذف میکنیم، [IMetier] (این نام آن در لایه Spring [métier] است) را به رابط [IMetierLocal] تغییر نام میدهیم، و از Spring برای نمونهسازی آن استفاده میکنیم:
package beans;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import rdvmedecins.metier.service.IMetier;
public class Application {
//لایه کسبوکار
private IMetier metier;
// خطاها
private List<Erreur> erreurs = new ArrayList<Erreur>();
private Boolean erreur = false;
public Application() {
try {
// نمونه سازی لایه [métier]
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config-metier-dao.xml");
metier = (IMetier) ctx.getBean("metier");
} catch (Throwable th) {
// خطا ثبت شد
erreur = true;
erreurs.add(new Erreur(th.getClass().getName(), th.getMessage()));
while (th.getCause() != null) {
th = th.getCause();
erreurs.add(new Erreur(th.getClass().getName(), th.getMessage()));
}
return;
}
}
// گیرندهها
public Boolean getErreur() {
return erreur;
}
public List<Erreur> getErreurs() {
return erreurs;
}
public IMetier getMetier() {
return metier;
}
}
- خطوط ۲۰–۲۱: نمونهسازی لایه [métier] از فایل پیکربندی Spring. این فایلی است که توسط لایههای [métier] و [1] استفاده میشود. ما آن را در پروژه وب [2] کپی میکنیم:
![]() |
- خطوط ۲۲–۳۱: ما هرگونه استثنا را مدیریت کرده و ردگیری پشته (stack trace) آنها را ثبت میکنیم.
پس از انجام این کار، بیون [Application] دیگر هیچ خطایی ندارد. اکنون بیونهای [Form]، [1] و [2] را بررسی میکنیم:
![]() |
ما تمام خطوط حاوی خطا (واردات و حاشیهنویسیها) را که به دلیل فقدان بستهها ایجاد شدهاند، حذف میکنیم. این کار برای از بین بردن تمام خطاهای [3] کافی است.
![]() |
علاوه بر این، گتر و ستر برای فیلد
// بیان برنامه
private Application application;
برخی از حاشیهنویسیهای حذفشده از بی́nهای [Application] و [Form]، کلاسها را بهعنوان بی́nهایی با دامنهٔ مشخص اعلام میکردند. این پیکربندی اکنون در فایل زیر تعریف شده است: [faces-config.xml] [4]:
<?xml version='1.0' encoding='UTF-8'?>
<!-- =========== FULL CONFIGURATION FILE ================================== -->
<faces-config version="2.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<application>
<!-- فایل پیام -->
<resource-bundle>
<base-name>
messages
</base-name>
<var>msg</var>
</resource-bundle>
<message-bundle>messages</message-bundle>
</application>
<!-- بیان applicationBean -->
<managed-bean>
<managed-bean-name>applicationBean</managed-bean-name>
<managed-bean-class>beans.Application</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<!-- بیان فرم -->
<managed-bean>
<managed-bean-name>form</managed-bean-name>
<managed-bean-class>beans.Form</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>application</property-name>
<value>#{applicationBean}</value>
</managed-property>
</managed-bean>
</faces-config>
بهطور معمول، انتقال اکنون کامل شده است. با این حال، هنوز چند جزئیات جزئی باقی مانده است. میتوانیم اجرای برنامه وب را امتحان کنیم.
![]() |
ما این کار را به خواننده واگذار میکنیم تا این اپلیکیشن جدید را آزمایش کند. میتوانیم آن را کمی بهبود دهیم تا در صورتی که инициализация (ابتداییسازی) bean [Application] با شکست مواجه شود، با آن مقابله کند. میدانیم که در این حالت، فیلدهای زیر инициализация شدهاند:
//خطاها
private List<Erreur> erreurs = new ArrayList<Erreur>();
private Boolean erreur = false;
این سناریو را میتوان در متد init از بیون [Form] مدیریت کرد:
@PostConstruct
private void init() {
// آیا فرایند инициализация به خوبی انجام شد؟
if (application.getErreur()) {
// بازیابی فهرست خطاها
erreurs = application.getErreurs();
// نمايش خطاها نمایش داده میشود
setForms(false, false, true);
}
// کش کردن پزشکان و مشتریان
...
}
- خط ۵: اگر دانه [Application] به اشتباه مقداردهی شده باشد،
- خط ۷: بازیابی لیست خطاها،
- خط ۹: و صفحهٔ خطا نمایش داده میشود.
بنابراین، اگر SGBD و MySQL را متوقف کرده و برنامه را مجدداً راهاندازی کنیم، اکنون صفحه زیر را دریافت میکنیم:

7.2. Conclusion
مهاجرت برنامه PrimeFaces / EJB / GlassFish به محیط PrimeFaces / Spring / Tomcat ساده بود. مشکل نشت حافظه که در تحلیل برنامه JSF / Spring / Tomcat (بخش 4.3.5) گزارش شده بود، همچنان پابرجاست.
این مشکل به همان روش برطرف خواهد شد.
7.3. آزمایش با اکلیپس
![]() |
ما پروژههای Maven را به Eclipse وارد میکنیم ([1]):
ما پروژه وب [2] را اجرا میکنیم.
![]() |
ما سرور Tomcat را انتخاب میکنیم [3]. صفحهٔ اصلی برنامه سپس در مرورگر داخلی Eclipse نمایش داده میشود [4].









