问题描述
for (...) {
UserList userList = (UserList) Component.getInstance(UserList.class, ScopeType.METHOD);
userList.getUserByEmailAddress(emailId);
}
Seam 支持不同的 ScopeType(例如 METHOD、PAGE、EVENT、APPLICATION).我们目前使用 METHOD 范围通过电子邮件 ID 检索用户对象.上面的代码存在于 for 循环中(即,对于我们检索用户对象的用户电子邮件地址集合).这是正确的 ScopeType 还是将 UserList 声明移到 for 循环上方更可取
There are different ScopeTypes which are supported by Seam (e.g. METHOD, PAGE, EVENT, APPLICATION). We currently use the METHOD scope to retrieve User object by email id. The above code is present in a for loop (i.e. for a collection of user email addresses we retrieve the user object). Is this the right ScopeType or would it be preferable to move the UserList declaration above the for loop
我们在某些范围类型中观察到 userList 对象被重用,有人可以澄清它是如何工作的.seam 中是否有任何工具可以帮助您了解这些对象是如何被重用的(我们打开了一些跟踪日志记录,但是调用的次数太多,而且不太清楚)
We have observed in certain scope types that the userList object gets reused, can someone clarify on how it really works. Are there any tools within seam which will help you understand how these objects get reused (We turned on some trace logging, but there were too many calls which were being made and it was not quite clear)
推荐答案
ScopeType.METHOD 说
ScopeType.METHOD says
对会话 bean 或 JavaBean 组件的每次调用将一个新的方法上下文放入与当前线程关联的方法上下文堆栈中.当方法返回时,上下文被销毁.
Seam 的大部分功能是作为一组内置的 Seam 拦截器实现的.这里有一段API所说的MethodContextInterceptor(内置Seam拦截器)的代码
Much of the functionality of Seam is implemented as a set of built-in Seam interceptors. Here goes a piece of code of MethodContextInterceptor (built-in Seam interceptor) which API says
设置 METHOD 上下文并在调用期间取消 SFSB 代理
MethodContextInterceptor.java 请参阅下面的注释并与上面突出显示的文本进行比较
MethodContextInterceptor.java See comments bellow and compare with The highlighted Text above
@AroundInvoke
public Object aroundInvoke(InvocationContext ctx) throws Exception {
Component comp = getComponent();
String name = comp.getName();
Object target = ctx.getTarget();
Method method = ctx.getMethod();
Object[] parameters = ctx.getParameters();
/**
* beginMethod
*
* Takes care of putting a NEW method context onto the stack of method contexts
*/
Context outerMethodContext = Lifecycle.beginMethod();
try {
Contexts.getMethodContext().set(name, target);
Contexts.getMethodContext().set("org.jboss.seam.this", target);
Contexts.getMethodContext().set("org.jboss.seam.method", method);
Contexts.getMethodContext().set("org.jboss.seam.parameters", parameters);
Contexts.getMethodContext().set("org.jboss.seam.component", comp);
/**
* And after method return
*/
return ctx.proceed();
} finally {
/**
* endMethod Takes care of destroying The previous added method context
*/
Lifecycle.endMethod(outerMethodContext);
}
}
如您所见,我没有看到 ScopeType.METHOD 提供的任何特殊行为.我认为,Seam 项目的创始人 Gavin King 已经创建了 The ScopeType.METHOD 作为可以在后面使用的附加范围.即使是 Seam in Action 一书也没有涵盖 ScopeType.METHOD 范围.
As you can see, i do not see any special behavior provided by ScopeType.METHOD. I Think Gavin King, founder of Seam project, has created The ScopeType.METHOD as an additional scope which could be used posteriorly. Even Seam in Action book does not cover ScopeType.METHOD scope.
所以每次调用getUserByEmailAddress时,都会执行上面的例程.关于上下文,Seam in Action 书很清楚
So each Time you call getUserByEmailAddress, The routine above is performed. About context, Seam in Action book is clear
上下文定义了变量名的位置以及它存在的时间
因此,您想要的范围应该符合您的业务需求.
So your desired scope should draw your business requiment.
关于 EntityQuery ???这是 Seam in Action 书中所说的
About EntityQuery ??? Here goes what Seam in Action book says
如果您每次需要显示结果时都执行查询,则会对数据库施加压力.在另一个极端,如果你坚持结果太久,你最终会向用户提供陈旧信息,这可能会让他们感到困惑,或者更糟的是,导致他们犯错决定.
默认情况下,一些 Query 方法通过将结果缓存在类的私有属性中来避免冗余的数据库查询.但它可以被覆盖,因为你改变了
By default, some Query methods avoid redundant database queries by caching the results in a private property on the class. But it can be overrided since you change
- 查询限制参数
- 排序顺序
- 最大结果值
- 第一个结果偏移
- 通过调用 refresh() 手动清除结果
当你更新一些@Entity并且需要刷新存储的结果集时,最后一项很有用.您可以通过使用 Seam 事件来完成它.但是如果您总是想要一个新的结果集,请将您的 EntityQuery 设置为 ScopeType.EVENT 并在 for 循环之前使用它
The last item is useful when you update some @Entity and you need To refresh The stored result set. You can accomplish it by using a Seam event. But if you always want a fresh result set, set up your EntityQuery as ScopeType.EVENT and use it before for loop instead
UserList userList = (UserList) Component.getInstance(UserList.class, ScopeType.EVENT);
for (...) {
userList.getUserByEmailAddress(emailId);
}
Seam 和 Spring 作用域的并排比较
Here goes a side by side comparison between Seam and Spring scope
Seam Spring Suited for
ScopeType.STATELESS singleton Service, repositories, Thread-safe components
ScopeType.APPLICATION singleton Service, repositories, Thread-safe components
ScopeType.SESSION session User login
ScopeType.CONVERSATION - Page flow
ScopeType.PAGE - Server-side based component model
ScopeType.EVENT request Non Thread-safe components
注意 ScopeType.CONVERSATION 不等于 Spring web flow.Seam ScopeType.CONVERSATION 超越了 web 层.甚至持久性上下文也可以包含在对话上下文中.请记住,当您拥有基于服务器端的组件模型框架(例如 JSF、Wicket 等)时,ScopeType.PAGE 是有意义的……通常,当您拥有完整的 Java EE 环境和 ScopeType.APPLICATION 时,会使用 ScopeType.STATELESS您使用普通的 POJO 而不是 EJB.
Notice ScopeType.CONVERSATION is not equal To Spring web flow. Seam ScopeType.CONVERSATION goes beyond web layer. Even an persistence context can be included in conversation context. Keep in mind ScopeType.PAGE makes sense when you have a server-side based component model framework such as JSF, Wicket and so on... Usually, ScopeType.STATELESS is used when you have an fully Java EE environment and ScopeType.APPLICATION when you use plain POJOs instead of EJB.
这篇关于范围类型如何影响 EntityQuery 对象的重用方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!