这个名字有点令人困惑,因为SLSB可以拥有州。您只需要进行内务管理,这样就不会使用先前EJB调用中的状态。
回到清洁代码:我也喜欢在SLSB中使用实例变量。这样可以正常工作,如果你足够小心,你就不会遇到状态不一致的问题,因为每次公共方法调用都会覆盖状态。
到目前为止一切顺利。但是如果用过的bean回到池中会发生什么?它采取了它的状态。根据状态的大小,这可能是真正的内存泄漏。 JBoss非常慷慨地使用bean,它们产生了大量的内存,导致一些严重的内存消耗 - 无所不能。
因此,一种方法是在bean方法存在之前清理状态并将bean返回到池中。但在我看来,这应该是无用的代码。
有没有正确的方法来解决这个问题?在这种情况下,最佳做法是什么?
答案 0 :(得分:0)
让生活变得简单,只需输入参数即可。即使你可以做其他事情,显然从无状态EJB的意图来看,你不应该。
FWIW旨在实现零参数的目标对我来说似乎很愚蠢。瞄准少数,是的,但为了自己的利益而争取零只是愚蠢。
答案 1 :(得分:0)
按照Robert C. Martin的干净代码方法应该有一个 小签名。
通常我更愿意传入(传递对象)作为参数,这样我就可以改变我传入的内容而不影响方法签名。
另外,我更喜欢传入一个接口而不是实际的基类。
public void doSomething(IMyTransferObject arg){
...
}
IMyTransferObject
是接口
interface IMyTransferObject {
...
}
class TransferObject implements IMyTransferObject{
private String name;
private String game;
... accessor / mutator
}
最好的情况是没有参数的方法。相反它 建议使用状态变量。这真的很有用。但 那么无状态会话bean呢?
这不能虔诚地遵循,并且没有理由这样做,真的。
答案 2 :(得分:0)
来自http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html:
无国籍会话豆
无状态会话bean不维护 与客户的会话状态。当客户端调用 无状态bean的方法,bean的实例变量可能包含 特定于该客户的状态,但仅限于该客户的持续时间 调用。方法完成后,客户端特定的状态 不应保留。但是,客户可能会改变状态 池化无状态bean中的实例变量,并保持此状态 到下一次调用池化无状态bean。除了 在方法调用期间,无状态bean的所有实例都是 等效,允许EJB容器为任何实例分配实例 客户。也就是说,应该应用无状态会话bean的状态 所有客户。
我不是EE的专家,但这听起来对我来说技术上允许按照你的计划使用字段。
我认为您拥有以确保每次调用新方法时,实例字段都会使用新数据进行更新,我认为您应该确保您在方法结束后删除引用,以确保不会阻止旧对象的垃圾收集,因为它们是在一些仍保留在某个池中的“旧”bean中引用的。
我会建议这样的模式:
public class MyBean{
private SomeClass firstObject;
private SomeOtherClass anotherObject;
private AndAnotherClass thirdObject;
public void theMethod(firstObject, anotherObject, thirdObject){
try {
this.firstObject = firstObject;
this.anotherObject = anotherObject;
this.third = thirdObject;
startProcessing();
}finally {
this.firstObject = null;
this.anotherObject = null;
this.third = null;
}
}
private void startProcessing() {
doStep1();
doStep2();
doStep3();
}
[...]
}
仍然有很多代码 - 但是如果你坚持这种风格,你会自动跳过“theMethod”部分并继续阅读“startProcessing”,在那里你可以干净利落地拥有所有东西。
答案 3 :(得分:0)
将实例变量保存在SLSB中是完美的,因为您不使用代理会在方法之间进行调用。例如:
@Stateless
public class MyEJB {
private String var;
public void receiveVar(String var) {
this.var = var;
useVar();
}
private void useVar() {
// do something with var
}
}
重点是:当您将此SLSB注入另一个时,任何方法调用都将通过代理来实现实际的EJB。因此,考虑到在代理实例上调用方法时从池中检索实例,不能保证代理将在两个或多个调用之间使用相同的池实例。所以不可能确保任何声明的类属性的值。
当SLSB回到池中时,它会自行获取每个设置的值(我认为它可能会根据供应商而变化,我并不确定)。但是,池化的SLSB实例已经具有先前配置的属性值是完全可能的(并且是可接受的)。
我在这里没有理解你的观点:
到目前为止一切顺利。但是如果用过的bean回到池中会发生什么? 它采取了它的状态。这取决于州的大小 可能是真正的内存泄漏。 JBoss对豆类非常慷慨 产生了很多它们导致一些严重的记忆 消费 - 无所事事。
你有什么例子"大州"你可以拥有SLSB吗?
最后:
我认为处理值的最佳方法始终是处理您将要使用的状态变量。使用前设置和清洁。最好的做法是避免这种令人困惑的情况。
希望它有所帮助。