EJB 用来数据池持久化 版本3.0 主要是做分布式应用程序。分布式指从服务器上拿业务,分布式把代码分成多个服务器上,通过一台调用另外一台。 EJB是j2ee的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。 在j2EE里,Enterprise java Beans(EJB) 称为java企业Bean,是java的核心代码, 分别是: 会话Bean(Session Bean),类似于写业务。实体Bean(Entity Bean)和 消息驱动Bean(MessageDriven Bean)类似Ajax, 1. Session Bean用于实现业务逻辑,它可以是有状态的,也可以是无状态的。Session Bean可以直接访问数据库,但更多的时候,它会通过Entity Bean实现数据库访问。 有状态:就像是单例。 无状态:就像每次都new一个类。 2. Entity Bean 实体Bean是用于实现OVR映射。 3. (MessageDriven Bean)消息驱动类似Ajax,发布过去,调用不用等待 什么是EJB? 一个技术规范:EJB是一种标准描述了构建应用组件要解决的。 可扩展(可以放在一个服务器上面,扩展性较好),分布式() , 事务处理(可以采用注入,采用aop思想), 数据存储(实体Bean) 安全性 对比: Ejb2.0复杂性,Ejb3.0结合hibernate思想,aop,spring思想,功能强大, 1. Ejb3.0不需要像Ejb2.0需要两个接口(远程接口,本地接口)一个Bean实现类 2. jdk代替实体Bean 3. 引入了拦截器 怎样运行Ejb服务器? Jboss(软件是免费的) webLogic(要钱的), 称为应用服务器, 必须用这些服务器才能发布EJB Jboss5.0 : 把两个类导入成jar包放在Server/ default / depley目录下 应用: 1. New 一个java项目, 2. 导入包——在压缩文件client / 里的文件都导入进里 Import javax.ejb.local; 3. New包,建session Bean——建一个接口,say()方法。 写实现类——实现上面接口,return一个值。 4. 把两个类导入成jar包放在C盘的jboss-4.2.3.GA / Server/ default / depley目录下 5. 写Test类: Try{ InitialContext ctx = new InitialContext(); HelloSessionIf He = (HelloSessionIf)ctx.lookup(“helloSessionIf/remote”) //得到远程的对象 System.out.println(he.say(“你好”)); }catch(Exception ex){ ex.printStackTrace(); } 6. 启动服务。启动jboss 4.x 7. 访问:http:localhost:8080 远程@Remote ,是SessionBean是远程出去给别人调用的。可以在不同服务器上调用 本地@Local(默认的),只能在同一台服务器上调用。 @Stateless(无状态的) 改端口:conf / jboss-service.xml, 配置怎样去拿数据,写数据 = org.jnp.interfaces.NamingContextFactory = localhost:8080 JNDI去拿数据源的,按jndi去发布数据,然后就可以从它拿数据了。 用Web项目调用服务器,不需要导入包,导入就会冲突了。 Java项目为什么还要加jobss包呢?为了是在开发的时候不会报错。 所有方法都发布在jobss服务器上面,一点击就调用服务器里的方法, 可以发布在同一台jobss服务器上, 用local @local({Hello . class}) 。lookup(“helloSessionIf / local”) 可以发布在不同一台服务器上,比如启动两个服务,jboss4.x和jboss5.x 用remote @remote({Hello . class}) 。lookup(“helloSessionIf / remote”) 作为测试项目的一定要导入包,java项目跟他不是同一个环境,调用项目一定要remote, 因为发布在不同jobss New工具,选择Ejb5.0 勾上。发布是.jar 使用工具,是方便发布。 会话Bean 定义两个接口,两个接口里有不同方法,接口实现远程接口方法,指明哪些是远程接口,哪些是本地接口。 @Remote({RI.class}) //@Remote({RI.class,LI.class})可以指明多个接口 @Local(LI.class) //@Local({RI.class,LI.class}) //实现两个接口 public class MyBean implements RI,LI{ public void r1() { System.out.println("r1"); } public void l1() { System.out.println("l1"); } Ejb的方法接受一个对象的。 业务方法接收的是一个对象的,对象必须要实现序列化 Public void ifm2(User user){ } //对象实现序列化 Public class User implements Serializable{ } @ejb //(name = “B2”)可以自己指明 If2 b2; 有实现这个的接口的就可以把这个类注入进来, 实体Bean采用JPA实现的 1. @Entity @Id @GeneratedValue(strategy=GenerationType.IDENTITY) 2. 配置信息: <persistence xmlns="http://java.sun.com/xml/ns/persistence" <persistence-unit name="sample" transaction-type="JTA"> //持久化单元 <jta-data-source>java:/MSSQLDSaa</jta-data-source> //连接的数据源 <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect"/> </properties> </persistence-unit> </persistence> <jndi-name>MySqlDS</jndi-name> 写配置文件放在deploy里面,mssql-ds.xml,主要写url ,user-name。 放在default下面 3. @PersistenceContext //(name = “sample”), name指配置信息里(persistence.xml)持久化单元的名称 4.写完业务之后发布到jobss 事务 Spring事务传播属性,7种 Ejb有6种。 REQUIRED:支持当前事务,如果没有事物就新建一个事物。 RequiresNew:新建事物,如果当前事务存在,把当前事务挂起。每次都会产生一个新的事务。原来的事务出现异常跟现在的没有关系。 SUPPORTS:如果有事物就跟着事物。 NOT_SUPPORTED:不支持事物。 NEVER:如果当前存在事物就抛异常,如果没有就 Mandatory:一定要支持事物,如果没有事物就抛异常。 NESTED:嵌套的。支持当前事务,新增savepoint点。类似之前设一个断点,让事物去处理。(ejb没有这条) Ejb事务传播有6种 事务写在业务层,默认的是required , 可以不用写。 在业务方法 @TransctionAttribute(TransctionAttributeType . REQUIRED_NEW) // 说明这个方法是重新启动一个事务 往数据库里进行一些操作,不管第一条(用的是required)数据库成功不成功,第二条(用的是required_new)都往数据库里插入。 消息驱动Bean JMS支持两种消息传递模型: 点对点(point-to-point,简称PTP),采用堆列 。 发布/订阅(publish/subscribe, 简称 pub /sub),采用的是广播。 点对点消息传递规定是:一条消息一发送只能传递给一个接收方 订阅消息传递规定是::一条消息一发送就可以传递给多个接收方 当一个方法执行很久的时候,就用JMS 注释说明消息驱动Bean 使用点对点(采用堆列,没有打印两条数据)的: @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination", propertyValue = "queue/myqueue") }) 在服务器端: 写一个类继承QMDB implements MessageListener public class QMDB implements MessageListener { public void onMessage(Message arg0) { // arg0 传文本的 //传文本:TextMessage textMessage =session.createTextMessage("bbbbbbb"); //传对象TextMessagetextMessage=session.createObjectMessage("bbbbbbb"); try { TextMessage textMessage = (TextMessage) arg0;//接收文本 System.out.println(textMessage.getText() + "::::::"); } catch (Exception e) { e.printStackTrace(); } } } 使用Topic(采用广播的,打印两条数据)的: 客户端:Topic @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"), @ActivationConfigProperty(propertyName="destination", propertyValue = "topic/myTopic") })