理想情況下,User
對象將有一個返回List<UnownedObject>
的方法,以便調用者可以獲得乾淨的API。一種方法是讓User
對象具有DAO實例,以便它可以要求DAO執行查詢。
爲了做到這一點,PersistenceManager
直到請求結束才能關閉。這樣做的一個方法是創建一個servlet filter:
public class PersistenceManagerFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
PersistenceManager pm = PMF.get().getPersistenceManager();
try {
request.setAttribute("pm", pm);
chain.doFilter(request, response);
} finally {
pm.close();
}
}
}
然後你就可以注射PersistenceManager
到你的DAO。如果你使用Guice你可以這樣做:
@RequestScoped
public class UserDao {
private final PersistenceManager pm;
@Inject
UserDao(PersistenceManager pm) {
this.pm = pm;
}
public User getUser(parameters) {
Key key = createKey(parameters);
User user = pm.getObjectById(User.class, key);
user.setUserDao(this);
return user;
}
}
這個工作最好時UserDao
是在同一個包User
所以User.setUserDao()
可以包範圍。您可以決定將PersistenceManager
設置爲User
對象而不是UserDao
。
接下來,您需要創建一個吉斯模塊綁定PersistenceManager
:
public class PersistenceManagerModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides @RequestScoped
PersistenceManager providePersistenceManager(HttpServletRequest request) {
return (PersistenceManager) request.getAttribute("pm");
}
}
最後,你需要配置Google App Engine to use Guice。
這只是一種可能的方式來做到這一點。您可以更聰明地擁有providePersistenceManager
創建PersistenceManager
並將其存儲爲請求屬性,而不是讓servlet過濾器創建PersistenceManager
(過濾器仍將關閉它)。您也可以讓servlet過濾器獲得Guice Injector,這樣您就可以避免使用setAttribute()
和getAttribute()
,而是使用更安全的API。
如果你使用Guice的ServletModule,這更容易,因爲你可以讓Guice將PersistenceManager注入PersistenceManagerFilter,所以你不必使用request.getAttribute()。在這種情況下,PersistenceManagerModule只會調用PMF.get() – NamshubWriter 2009-08-07 00:46:47