EJB的用途是什么

Rae*_*ald 27 java ejb java-ee

我目前正在学习Jave-EE,拥有丰富的C++经验并且学过Java SE.我不明白Enterprise Java Beans的目的; 有人可以为我澄清这一点.我对遗留用途不感兴趣:这是在EJB-3.1和Java-EE 6的上下文中.

似乎有些人使用它们来包含业务逻辑,用于实现传统3层架构的业务层.这将域逻辑与域对象分开,导致贫乏的域模型.但这违背了我所有的OOD本能; 我同意Martin Fowler认为这是一种反模式.我是否应该放松对贫血领域模型的反对意见?或者EJB有其他用途吗?

Arj*_*jms 22

正如其他几个答案所示,EJB非常适合实现服务层.它们是Java EE中非常现代,轻量级的bean.尽管有这个名字,你无法将它们与J2EE中严酷的重型EJB2野兽进行比较.每个人都同意那些是灾难,但它不再是2002年了.

从EJB3(2006)开始,EJB bean就是一种非常精细的技术.

他们通过提供声明性事务来帮助很多(如果一个事务尚未进行,每个入口方法都会自动启动事务,尽管如果需要可以更改它),池化,安全性,锁定,远程处理等等.有关其他详细信息,请参阅以下答案:

这里已经解释了交易,但是要补充一点:它不是高度复杂,高度安全的系统所需要的.即使只处理数据库,我也会说它是一个基本要求.如果我处理一个简单的订单,我希望库存和订单都更新或两者都没有.这与在数据库中使用PK和FK以确保完整性一样基本.

EJB使管理事务变得微不足道.没有EJB,有很多用于启动,提交或回滚tx的样板代码.

人们也不应低估EJB提供的池和存根的好处.这意味着bean可以注入大量的EJB,并且您不必担心每次创建这样的bean时都会对它们进行实例化.如果不是每次都使用所有EJB,那么这将特别麻烦.

但是,由于池化,只注入非常轻量级的存根,这更类似于指向实际实例的一种URL.这些在注入的内存或CPU开销方面几乎没有任何成本.

EJB还具有注释来声明它们是单例,安排它们的锁定行为(写锁定/读锁定),声明应该在启动时启动,允许它们管理所谓的扩展持久化上下文(不限于TX的持久化上下文) )等

这些都是您在苗条实体中不想要的问题.在许多体系结构中,例如,User对象是我想跨层发送的简单数据实体.我不希望我的User实例具有sendMsg()方法并且具有JMS资源作为依赖项,因此可以突然从某个客户端发送消息.我不确定为什么人们会认为这是'自然'和'OOP'.

在现实世界中,每当我想给他发明信片时,我也不会对我的朋友Joe调用sendMsg操作.相反,我发一张卡片并将其带到邮局或放在邮箱中.

我也没有在蛋糕上调用bake()操作.相反,我把蛋糕放在烤箱等.


Hei*_*upp 6

您已经引用了"实现业务逻辑"用例.

EJB - 在EJB 3.x会话Bean,消息驱动Bean和3.1中,新的Singleton Beans确实允许您实现biz逻辑.会话Bean通常作为客户端连接的Facade服务器.这些客户端可以是Servlet,通过例如HTTP或"胖"客户端来提供内容,这些客户端通过其他(更多二进制)协议与EJB进行通信.

Message Driven Beans作为异步通信的端点,可以自己调用Session Beans上的方法作为示例.

所有EJB都有一个共同点,这使它们非常有吸引力:它们由容器管理.因此容器负责实例化,池化,事务,安全性等.

如果你在EJB中写

@Resource DataSource x;
Run Code Online (Sandbox Code Playgroud)

容器确保当bean准备好接收方法调用时,变量"x"包含合适的数据源.

Beans池可以让你有更多的客户端连接到一个站点而不是你没有,因为实例是共享的(无状态SB),或者如果内存很紧,那么容器可以将实例交换到第二存储 - 稍后激活它们.

在EJB 3中,EJB 1.x和2.x中的旧EntityBeans消失了,取而代之的是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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • http://stackoverflow.com/questions/4773927/in-what-situations-are-ejbs-used-are-they-required-in-websites-web-application/4775719#4775719强调"必须启动和提交/回滚事务自己消失了" (3认同)

vic*_*irk 6

使用Java EE并不会自动暗示一个贫血的域模型,就像你可以用java编写代码那样没有充分利用最佳实践并不意味着它在java中是不可能的.我相信Martin Fowler的观点是J2EE(注意使用J2EE而不是Java EE)几乎强制执行逻辑和数据操作.使用基于POJO的实体允许数据和行为适当地建模.EJB中的"业务逻辑"通常编排业务逻辑的应用程序,但通常不会实际执行它,它通常是一个非常薄的包装器.

因此,EJB构成了您的Service API,您需要使用您正在使用的任何平台/框架,您需要拥有可以物理调用的东西,这是一个切入点.无论您是使用spring,Web服务等实现......您需要一个服务层,没有什么能阻止它在Java EE中实现.一个颇为人为的例子

@Stateless
public SomeServiceImpl implements SomeService
    someServiceMethod() {
       delegate.doSomething();
    }
}

public SomeServiceDelegate implements SomeService
    someServiceMethod() {
       modelObject.doSomething();
    }
}
Run Code Online (Sandbox Code Playgroud)

我没有考虑更喜欢EJB而不是任何其他技术的原因,只是想指出使用它们并不意味着你的实现不能使用最佳实践.

  • 此链接可能是您感兴趣的http://www.infoq.com/articles/ddd-in-practice (2认同)

Mic*_*rdt 5

几点:

  • EJB本身不存在; 它们位于EJB容器中,通过它们为您提供一些非常有用的服务,例如声明性安全性,声明式事务和相对简单的集群.
  • 虽然贫血领域模型确实是反模式:一旦您的业务逻辑变得更加复杂,例如当多个应用程序在同一模型上运行时,将大部分逻辑与模型分离就成为关注点分离的问题.

  • @Suresh:那又怎样?EJB容器在Spring存在之前提供它们. (3认同)
  • @Raedwald:来自同一篇文章:"如果业务规则逻辑跨越两个或更多个Entity对象,那么它应该成为Service类的一部分." - 无状态会话EJB就是服务类.请注意,本文还将服务类视为域层的一部分. (3认同)
  • @Raedwald:不,我说在将所有*逻辑强行保留在域模型之外,并将更专业或复杂的逻辑放入单独的类中以实现关注点分离之间存在差异. (2认同)