下面案例使用的環境
-------------1.jboss 的安裝
http://www.jboss.org/jbossas/downloads
jboss 的啟動?? jboss/bin/run.bat?
停止服務? 使用個 ctrl+c 就可以了
什么是EJB???
會話bean
實體bean
消息驅動bean
//----遠程調用 EJB的過程
///EJB 容器對會話bean的管理方式
//----------------EJB中? 怎么樣使用其他 EJB
//---- EJB中的一些注解說明
--定義 本地和遠程 接口類
//開發的時候 需要先加入 jboss安裝路徑下 client 中的jar
開發好項目后, 選擇好文件后? 將項目打成 jar 放入到 jboss 安裝目錄下的
E:\jboss-5.0.0.GA\server\default\deploy
HelloWorld.java
HelloWorldLocal.java
Other.java
//遠程 和 本地 接口實現類?
HelloWorldBean.java
OtherBean.java
-->使用 Ant 編譯發布后 就可以 在jboss 后臺空中中查看 發布到 接口 (下面有介紹怎么查看)
客戶端 client 開發 訪問遠程接口的客戶端
客戶端 client 開發 訪問本地接口的客戶端
//注意? 注意 下面的 web項目 添加 對上面 ejb3.0 項目的引用? 否則 jsp頁面會報錯?
//編寫好后將香項目 打成 war的包 發布到? server\default\deploy下
////----------? ANT 的 使用
提高工作效率?? 幫助 我們編譯 打包? 發布運行? 卸載
在項目根目錄下 添加一個 build.xml
然后配置?
在? 中查看 jndi 名稱
//---jboss 默認生成的JNDI 名稱
myeclipse.10.1 jdk1.6.0_17 jboss-6.0.0.Final JAXWS2.2.7-20120813
-------------1.jboss 的安裝
http://www.jboss.org/jbossas/downloads
-------------jboss 要配置jdk JAVAHOME CLASSPATH 端口 8080 1099 findstr不是內部命令 外部命令 %SystemRoot%\system32;%SystemRoot%; 環境配置 JBOSS_HOME=d:\JBOSS\jboss-4.2.2.GA PATH=$PATH;%JBOSS_HOME%\bin;
jboss 的啟動?? jboss/bin/run.bat?
停止服務? 使用個 ctrl+c 就可以了
什么是EJB???
EJB (Enterprise JavaBean)是一個標準的分布式業應用服務器端組件. EJB實際上是用于編寫業務層代碼.他為我們提供了很多服務,如事務管理,多用戶安全,持久化.分布式. EJB 主要使用于大型企業,因為一般大型企業都有多個信息系統,而這些系統中的信息都是相互關聯的,因此為了避免業務功能重復開發,所以我們將一些業務給獨立出來,讓這多個信息系統共享一個業務中心.這樣我們開發應用就需要具備分布式的能力.因此我們采用EJB 如果不需要開發分布式應用完全可以采用spring來開發. 優點: 使用EJB架構編寫的應用 是可以伸的 事務性,多用戶安全,的. EJB3.0 運行的環境 jdk5.0 以上 jboss 4.2 以上 :javaEE應用服務器所占據的市場份額第一. weblogic 10以上: 在商業市場上占有率第一 sun applicatioin server 9.0 以上 oralce application server 10 以上:如果數據庫是oracle apusic引用服務器 中國開發的. Glassfish:開源的javaEE服務器, 對JavaEE規范支持的非常好, 運行性能比較高,發展實際較短.
會話bean
負責和客戶端的交互,是編寫業務邏輯的地方,在會話bean中可以通過jdbc直接遭挫數據庫,但是大多數情況下都是過實體bean來完成對數據庫的額操作 1.無狀態會話bean 平常,我們使用最多的無狀態bean因為它的bean 的實例,可以供多個用戶使用,所以它的性能高,正因為一個bean實例可以被多個用戶使用,那么前一個用戶設置的值有可能被后一個用戶所修改,所以它無法正確保存某個用戶設置的值,因為是無狀態的. 2.有轉臺會話bean 有狀態bean平常使用的不多, 因為他的一個bean 實例只能供一個用戶使用個,所以要為每一個用戶創建一個實例,所以性能開銷比較大,正因為他的實例,只被一個用戶使用,那么用戶設置是不會背其他用戶所 修改,所以可以正確保存用戶設置過的值,因此是有狀態的.
實體bean
它實際上屬于java持久規范 簡稱JPA里的技術,JPA的出現主要是為了簡化現有的持久化開發工作和整合ORM 技術.借宿現在在Hibernate toplink 等 ORM框架各自為營的局面,用于實現O/R映射,負責將數據庫中的表記錄映射為內存中的Entity對象,
消息驅動bean
它是專門用于一部處理java 消息的組件,具有處理大量并發消息的能力,它基于JMS消息,只能接收客戶端發送的JMS消息然后處理。MDB實際上是一個異步的無狀態Session Bean,客戶端調用MDB后無需等待,立刻返回,MDB將異步處理客戶請求。這適合于需要異步處理請求的場合,比如訂單處理
//----遠程調用 EJB的過程
首先 客戶端需要與EBJ建立起 socket 通信; 在通信管道上他們之間需要來回發送IIOP協議信息; (Internet Inter-ORB Protocol(互聯網內部對象請求代理協議),它是一個用于CORBA 2.0及兼容平臺上的協議)實現互操作性的協議,由不同語言編寫的分布式程序在因特網中可以實現彼此的交流溝通,公用對象請求代理程序結構(Common Object Request Broker Architecture,CORBA)中至關重要的一個部分 因為數據要在在網絡上進行傳輸, 所以存放數據的 java對象必須要進行序列化

在這個過程中我們看到 ,網絡通信的開銷, 協議解析的開銷 ,對象序列化的開銷. A: (遠程接口 ) 客戶端 和 EJB 容器不在一個 同一機器上 1.可以看出 EJB容器是 一個 重量級容器 所以 初始化 需要比較長的時間 2.EJB 是分布式技術,他允許客戶端 與 EJB應用不在同一機器上,所以 這樣開銷也是必然的 B .(本地接口 ) 不注解的時候 默認為 本地接口 客戶端 和 EJB 容器在一個 同一機器上 這樣 是不是就可以 減少了 網絡 通信 協議解析的開銷呢 ?? 1.是滴,會減少 , 此時 他們 就跑到了 JVM 內存中了,他們之間完全可以通過內存進行交互. 所以此時 就需要 "本地接口了". 客戶端 和 EJB應用 發布在同一個jboss 我們就認為 在同一個JVM 內
///EJB 容器對會話bean的管理方式
1.無狀態 使用 @Stateless 用戶可以共享 EJB 容器會對 這個bean使用個實例池技術管理bean 實例池 和 數據源技術 原理相同, 比如數據源里面的連接 沒有空閑時候, 必須等連接使用完后才能使用. 這個實例 只有當一個用戶使用完后,才能被其他用戶使用. 可以使用最少的實例數 來為用戶服務. 2.有狀態 使用 (購物車) @Stateful 會為每個用戶創建單獨的一個bean實例 EJB 容器會對 這個bean 使用 激活(activation) 管理bean //鈍化 如果用戶 在一定時間內沒有使用 這段時間 < 會話超時 設置的時間 ==> 系統會講 用戶的這個會話信息保存到 磁盤里面 //激活 如果用戶又開始訪問 < 會話超時 設置的時間 ==> 此時 會將磁盤上的會話信息(釋放內存等資源) 又被還原到 內存中 此時用戶又可以繼續訪問了 //超時 如果用戶又開始訪問 > 會話超時 設置的時間
//----------------EJB中? 怎么樣使用其他 EJB
第一種: 使用 查找的方式 InitialContext ctx=new InitialContext(); Other other=(Other)ctx.lookup("OtherBean/local"); 第二種: 使用 注解的方式 @EJB 例如: public class HelloWorldBean implements HelloWorld,HelloWorldLocal { @EJB(beanName="OtherBean") Other other; // 如果這個接口 有多個 實現類 就出現錯 誤;此時就需要 beanName=就可以設置成需要的那個 public String sayHello(String name) { return name+"說:你好,"+other.sayMe(); } }
//---- EJB中的一些注解說明
1.指明為無狀態的會話bean @Stateless 2.指明為有狀態的會話bean @Stateful 3指明為遠程接口 @Remote(HelloWorld.class) @Remote(HelloWorld.class) //如果發布在同一機器上 就優先使用本地接口 否則 使用 遠程接口 4.指明 本地接口 @Local(HelloWorldLocal.class) 5.修改 類的 EJB 名稱 @Stateless(name="xxx") 可以將這個類的EJB名稱 修改為xxx 6.使用其他EJB 類 @EJB Other1 other; @EJB(beanName="OtherBean") Other other; // 如果這個接口 有多個 實現類 就出現錯誤;此時就需要 beanName=就可以設置成需要的那個 7.使用EJB自帶的服務 @Resource TimerService timerService; //使用 EJB 的定時服務 8.如果要使用 數據源 @Resource(mappedName="java:xxx") DataSource datasource; //mappedName 就是java類的 jndi名稱

--定義 本地和遠程 接口類
//開發的時候 需要先加入 jboss安裝路徑下 client 中的jar
開發好項目后, 選擇好文件后? 將項目打成 jar 放入到 jboss 安裝目錄下的
E:\jboss-5.0.0.GA\server\default\deploy
HelloWorld.java
HelloWorldLocal.java
Other.java
package com.sh.ebj3; //遠程接口 public interface HelloWorld { public String sayHello(String name); } package com.sh.ebj3; //本地接口 public interface HelloWorldLocal extends HelloWorld { } package com.sh.ebj3; //其他bean public interface Other { public String sayMe(); }
//遠程 和 本地 接口實現類?
HelloWorldBean.java
package com.sh.ejb3.impl; import javax.annotation.Resource; import javax.ejb.EJB; import javax.ejb.Local; import javax.ejb.Remote; import javax.ejb.Stateful; import javax.ejb.TimerService; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; import com.sh.ebj3.HelloWorld; import com.sh.ebj3.HelloWorldLocal; import com.sh.ebj3.Other; //指明為無狀態的會話bean @Stateless @Stateful //指明為遠程接口 @Remote(HelloWorld.class) @Remote(HelloWorld.class) //如果發布在同一機器上 就優先使用本地接口 否則 使用 遠程接口 //指明 本地接口 @Local(HelloWorldLocal.class) public class HelloWorldBean implements HelloWorld,HelloWorldLocal { @EJB(beanName="OtherBean") Other other; // 如果這個接口 有多個 實現類 就出現錯誤;此時就需要 beanName=就可以設置成需要的那個 //如果要使用 EJB里面的 定時服務 此時只能使用 不能使用 @EJB 服務 @Resource TimerService timerService; //使用 EJB 的定時服務 //如果要使用 數據源 數據庫可以減少數據庫連接的創建數量 ,因為 數據庫連接對象的創建是很耗性能的 . @Resource(mappedName="java:xxx") DataSource datasource; //mappedName 就是java類的 jndi名稱 private static int times=1; @Override public String sayHello(String name) { // TODO Auto-generated method stub try { times++; InitialContext ctx=new InitialContext(); Other other=(Other)ctx.lookup("OtherBean/local"); System.out.println(times); return name+"說:你好,"+other.sayMe(); } catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }
OtherBean.java
package com.sh.ejb3.impl; import javax.ejb.Stateless; import com.sh.ebj3.Other; @Stateless//@Stateless(name="xxx") 可以將這個類的EJB名稱 修改為xxx public class OtherBean implements Other { @Override public String sayMe() { // TODO Auto-generated method stub return "other"; } }
-->使用 Ant 編譯發布后 就可以 在jboss 后臺空中中查看 發布到 接口 (下面有介紹怎么查看)
客戶端 client 開發 訪問遠程接口的客戶端
package com.sh.test; import java.util.Properties; import javax.naming.InitialContext; import com.sh.ebj3.HelloWorld; public class EJBClient { public static void main(String [] args){ //Properties props=new Properties(); /*props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory"); props.setProperty("java.naming.provider.url", "localhost:1099");*/ /*如果訪問的是sun公司的服務器 props.setProperty("java.naming.factory.initial", "com.sun.enterprice.naming.SeriaIInitContextFactory"); props.setProperty("java.naming.provider.url", "localhost:3700"); */ try { //不采用硬編碼 就可以直接 添加 一個jndi.properties 講上面的配置寫入進入 InitialContext ctx=new InitialContext();//InitialContext(props); HelloWorld helloworld=(HelloWorld)ctx.lookup("HelloWorldBean/remote"); System.out.println(helloworld.sayHello("佛山")); } catch (Exception e) { e.printStackTrace(); } } }
客戶端 client 開發 訪問本地接口的客戶端
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page import="javax.naming.*,com.sh.ebj3.*" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <% try { //不采用硬編碼 就可以直接 添加 一個jndi.properties InitialContext ctx=new InitialContext();//InitialContext(props); HelloWorldLocal helloworld=(HelloWorldLocal)ctx.lookup("HelloWorldBean/local"); out.println(helloworld.sayHello("佛山詠春派")); } catch (Exception e) { e.printStackTrace(); } %> <body> This is my JSP page. <br> </body> </html>
//注意? 注意 下面的 web項目 添加 對上面 ejb3.0 項目的引用? 否則 jsp頁面會報錯?
//編寫好后將香項目 打成 war的包 發布到? server\default\deploy下
////----------? ANT 的 使用
提高工作效率?? 幫助 我們編譯 打包? 發布運行? 卸載
在項目根目錄下 添加一個 build.xml
然后配置?
<?xml version="1.0" encoding="UTF-8"?> <!-- ====================================================================== 2013-2-25 下午1:53:33 project description Bin ====================================================================== --> <project name="HelloWorld" basedir="."> <description> description </description> <!-- 設置項目原目錄 --> <property name="src.dir" value="${basedir}\src" /> <!-- 獲取環境變量 --> <property environment="env"/> <property name="jboss.home" value="${env.JBOSS_HOME}"/> <property name="jboss.server.config" value="default"/> <property name="build.dir" value="${basedir}\build"/> <!-- 引入 jboss client 下的 所有jar --> <path id="build.classpath"> <fileset dir="${jboss.home}\client"> <include name="*.jar"/> </fileset> <!-- 講編譯過后的路徑加入到 path中去 方便 接口和實現的引用 --> <pathelement location="${build.dir}"/> </path> <target name="prepare" description="創建build目錄"> <delete dir="${build.dir}"/> <mkdir dir="${build.dir}"/> </target> <!-- - - - - - - - - - - - - - - - - - target: compile - - - - - - - - - - - - - - - - - --> <target name="compile" depends="prepare" description="編譯"> <javac srcdir="${src.dir}" destdir="${build.dir}" includeantruntime="false"> <classpath refid="build.classpath"/> </javac> </target> <!-- ================================= target: ejbjar ================================= --> <target name="ejbjar" depends="compile" description="創建EJB發布包"> <jar jarfile="${basedir}\${ant.project.name}.jar"> <fileset dir="${build.dir}"> <include name="**/*.class"/> </fileset> </jar> </target> <!-- ================================= target: deploy ================================= --> <target name="deploy" depends="ejbjar" description="發布EJB"> <copy file="${basedir}\${ant.project.name}.jar" todir="${jboss.home}\server\${jboss.server.config}\deploy"/> </target> <!-- - - - - - - - - - - - - - - - - - target: undeploy - - - - - - - - - - - - - - - - - --> <target name="undeploy" description="卸載EJB"> <delete file="${jboss.home}\server\${jboss.server.config}\deploy\${ant.project.name}.jar"/> </target> </project> <!--//如果注意 編譯中的 includeantruntime="false" 的配置 否則 會報錯 如果 剛配置JBOSS_HOME 則需要重啟 IDE -->
在? 中查看 jndi 名稱
localhost:8080 --->JMX控制臺 --> service=JNDIView (jboss) -->list --> Global JNDI Namespace +- UserTransactionSessionFactory (proxy: $Proxy82 implements interface org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory) +- UUIDKeyGeneratorFactory (class: org.jboss.ejb.plugins.keygenerator.uuid.UUIDKeyGeneratorFactory) //找到了 +- HelloWorldBean (class: org.jnp.interfaces.NamingContext) | +- remote (class: Proxy for: com.sh.ebj3.HelloWorld) | +- remote-com.sh.ebj3.HelloWorld (class: Proxy for: com.sh.ebj3.HelloWorld) 如果有問題 可以看 導入的jar 環境變量的設置
//---jboss 默認生成的JNDI 名稱
當EJB發布到jboss時候 默認的命名規則為 1.如果 EJB 作為模塊打包進后綴名我*.ear 的javaEE 企業應用文件,默認的全局JNDI 是 本地接口 EAR-FILE-BASE-NAME/EJB-CLASS-NAME/local 遠程接口 EAR-FILE-BASE-NAME/EJB-CLASS-NAME/remote 例如 講 HelloWorld 應用作為模塊打包進名為 aaaa.ear 的企業文件 那他的 遠程接口的JDNI的名稱就是 aaaa/HelloWorldBean/remote --HelloWroldBean 為HelloWorld 的實現類 2.如果講EJB應用打包成后綴為*.jar 的模塊文件,默認的全局JNDI名稱是 本地接口 : EJB-CLASS-NAME/local 遠程接口 : EJB-CLASS-NAME/remote 例如 講 HelloWorld 應用作為模塊打包進名為 aaaa.jar 的企業文件 那他的 遠程接口的JDNI的名稱就是: HelloWorldBean/remote --HelloWroldBean 為HelloWorld 的實現類
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
