EJB使事务管理变得十分简单。如果没有EJB,启动、提交或回滚事务时就需要大量样板代码。
此外,不要低估EJB提供的池和存根(stubs)的好处。这意味着一个bean可以注入许多EJB,并且您不必担心每次创建此类bean时它们都会被实例化。否则,当不是每次都使用所有EJB时,这将特别麻烦。
由于存在池,因此只注入非常轻量级的存根,它们更类似于指向实际实例的URL。从内存或CPU开销的角度来看,这些存根的成本几乎为零。
EJB还具有注释,以声明它们是Singletons,安排它们的锁定行为(写锁/读锁),声明应该在启动时初始化一个实例,允许它们管理所谓的扩展持久性上下文(一个未限定到TX的持久性上下文)等。
这些都是您不希望出现在精简实体中的问题。在许多架构中,例如用户对象是一个简单的数据实体,我希望将其发送到各个层。我不想让我的User实例有一个sendMsg()方法,并且拥有一个JMS资源作为依赖项,以便可以从某个客户端突然发送消息。我真不确定为什么人们认为这样做在面向对象编程中很“自然”。
在现实世界中,当我想给我的朋友Joe寄明信片时,我也不会调用sendMsg操作。相反,我会写上地址并把它带到邮局或投递到邮箱里。
我也不会对蛋糕调用bake()操作。相反,我会把蛋糕放进烤箱里等它烤熟,等等。
@Stateless
public SomeServiceImpl implements SomeService
someServiceMethod() {
delegate.doSomething();
}
}
public SomeServiceDelegate implements SomeService
someServiceMethod() {
modelObject.doSomething();
}
}
@Resource DataSource x;
容器确保当您的bean准备好接收方法调用时,变量“x”包含合适的数据源。
Bean池化允许您拥有比没有池化更多的客户端连接到站点,因为实例可以共享(无状态SB)或者实例可以被容器交换到第二存储器中以释放内存并在后续重新激活它们。
在EJB 3中,EJB 1.x和2.x中的旧EntityBeans已经消失,由JPA取代。JPA构建了POJO的域数据模型,可以通过注释来提供关系语义,也可以通过外部XML文件提供语义。
使用JPA(完全不需要EJB),EJB通常用于实现这些实体的处理:
@Stateless
public class MyBean {
@PersistenceContext EntityManager em;
public Foo getFoo(String name) {
Query q = em.createQuery("SELECT f FROM Foo f WHERE f.name = :name");
q.setParameter("name",name);
return q.getSingleValue();
}
}
几个要点:
根据个人经验的一点评论...
我不怀疑EJB的好处,但是我曾经使用过它们,我认为EJB只适用于安全性和事务非常重要的情况(例如:金融应用)。对于90%的情况,您没有EJB也可以正常运作。另外...可扩展性和EJB并不是很友好。