[英]JSF design and @Stateless @EJB @PersistenceContext explanation/usage
我正在使用JSF(2.2)和EclipseLink(JPA 2.1)使用NetBeans 8.0.2構建Web應用程序。
假設當前功能是安靜的基本功能,包括:登錄,注銷,注冊,用戶角色,僅管理員可用的頁面(通過使用過濾器)等。
我已經閱讀了maaany SO的問答集(主要來自@BalusC ,謝謝!),並想驗證我的設計是否正確/遵循最佳實踐。
目前我有:
也許這個名字是多余的,但是我想要一個明顯的名字開頭),對應於數據庫中的用戶:
@Entity
@Table(name = "Users")
@XmlRootElement
@NamedQueries({
@NamedQuery(name = "UserEntity.findAll", query = "SELECT u FROM UserEntity u")...})
public class UserEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "userID")
private Integer userID;
...
}
它使用UserService
並保留一個相關的UserEntity
。 它的方法用在.xhtml文件的EL中
@ManagedBean(name = "user") // name not needed here, but I kind of like it
@SessionScoped
public class User implements Serializable {
private UserEntity userEntity; // with getter or make this public to be accessed directly from EL?
public String login() {
userEntity = UserService.find(username);
...
}
...
}
基本上有數據庫訪問方法:
public class UserService {
public static String insertUser(UserEntity user) {
String retMessage;
EntityManager em = JPAResource.factory.createEntityManager();
EntityTransaction tx = em.getTransaction();
tx.begin();
try {
em.persist(user);
tx.commit();
retMessage = "ok";
return retMessage;
}
catch (PersistenceException e) {
if (tx.isActive()) tx.rollback();
retMessage = e.getMessage();
return retMessage;
}
finally {
em.close();
}
}
...
}
在某個時候,我注意到UserService只能有靜態方法,因此我可以在不創建實例的情況下訪問它們。
那不好嗎?為什么?
我猜正確的方法是將UserService設置為:import javax.ejb.TransactionAttribute; 導入javax.ejb.TransactionAttributeType; ...
@Stateless
public class UserService {
@PersistenceContext
private EntityManager em;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public static String insertUser(UserEntity user)
{
em.persist(user);
}
...
}
而用戶bean為:
@ManagedBean(name = "user")
@SessionScoped
public class User implements Serializable {
@EJB
private UserEntity userEntity;
public String login() {
userEntity = UserService.find(username);
...
}
...
}
那是對的嗎?
我不確定@Stateless
, @Stateless
@EJB
, PersistenceContext
到底在做什么/意味着什么。 (它們分別來自javax.ejb.Stateless
, javax.ejb.EJB
, javax.persistence.PersistenceContext
嗎?)
使用@Stateless
和@EJB
是否可以使我使用UserService
而不創建它的實例並且沒有靜態方法?
如何檢查交易呢? @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
是否覆蓋了我? 即不需要進一步檢查? 如果拋出異常,該方法將return
相關消息嗎?
使用@PersistenceContext
,什么/誰在創建EntityManager
實例?
這種設計是否是良好的做法,同時考慮到關注點分離等問題?
謝謝!
@Stateless
是替代靜態方法的方法。 如果您使用NetBeans,則可以自動生成這些@Stateless
類,它們在此稱為Facades(在NetBeans->右鍵單擊pacakge-> new->會話Bean中選擇實體類,然后選擇實體)。
您不必自己創建EJB
實例,只需使用@EJB
批注,容器將為您提供“實例”。
對於事務,您具有單獨的注釋,可以閱讀有關javax.ejb.TransactionAttribute
。 您只需使用它們注釋EJB
類/方法,並給定javax.ejb.TransactionAttributeType
,這就是一切,容器將為您啟動/結束/嵌套(阻止)事務。
對於@SessionScoped
它可以作為您的控制器。 假設您有5個xhtml頁面。 然后創建5個支持bean( @RequestScoped
@ViewScoped
/ @ViewScoped
等),並將每個@Inject
與控制器類一起使用。 因此,您的支持bean將其邏輯范圍縮小到只有一頁,然后將進一步的操作轉發到控制器類。 控制器類只能具有僅1行的方法(API),用於將操作轉發到EJB
。 在EJB中,您可以具有與該控制器進行通信的服務( @Stateful
),該服務與其他類進行通信(例如以前支持Bean,但現在僅稱為管理器),並且管理器具有業務邏輯。 此邏輯可以通過先前生成的外觀( @Stateless
)將數據持久保存到數據庫。
您不需要使用EJB
過濾器來控制角色,可以使用批注javax.annotation.security.RolesAllowed
並指定可以由哪個角色調用的方法。
這是我的觀點,它可能不是一個復雜的解釋,但是您可以使用關鍵字在Google上搜索很多人員。
編輯:
不要使用@ManagedBean
和@ManagedProperty
類的JSF注釋。 最好使用更新的技術,例如CDI @Named
和@Inject
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.