<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 195, comments - 34, trackbacks - 0, articles - 1

    EJB3.0中的依賴注入,截獲器及其在WebLogic Server 10中的擴(kuò)展2007-09-05 來自:lizhe1985  [收藏到我的網(wǎng)摘]



    1 前言

      與EJB2.1相比,EJB3.0規(guī)范引入了兩個重要概念:依賴注入(DI:Dependency Injection)和截獲器(Interceptor),本文首先介紹了這兩個概念并給出相關(guān)示例,然后分析了EJB3.0規(guī)范在這兩方面的不足之處,最終深入探討了WebLogic Server 10對它們的支持和擴(kuò)展。

    2 依賴注入

      2.1 基本概念

      依賴注入是從開源社區(qū)的一些著名輕量級容器(如Spring、Pico container)中所發(fā)展出來的概念,其主要思想就是由容器而不是對象本身來負(fù)責(zé)處理對象之間的依賴關(guān)系。與傳統(tǒng)的服務(wù)定位器相比,依賴注入具有易測試、弱侵入性等優(yōu)點,這也就是為什么在最新的Java EE 5規(guī)范中引入它的原因。

      對于EJB3.0來說,依賴注入就是由容器負(fù)責(zé)查找被依賴的對象并注入到依賴bean中,而bean本身不再需要進(jìn)行JNDI或者context查詢。此外,依賴注入發(fā)生在任何業(yè)務(wù)方法被調(diào)用之前,而且支持setter方法注入和域注入兩種方式。

      通過與標(biāo)注結(jié)合使用,在bean類中聲明依賴注入是非常簡單的(當(dāng)然,也可以在部署描述符文件中聲明依賴注入):

        @EJB用于注入EJB業(yè)務(wù)對象
        @PersistenceUnit 用于注入EntityManagerFactory
        @PersistenceContext 用于注入EntityManager
        @Resource 用于注入其它資源對象,如連接工廠、消息目標(biāo)等

      2.2 示例

    @Stateless
    public class ServiceBean implements Service {
    private javax.sql.DataSource myDS;
    @Resource(mappedName=“LocalDataSource")
    public void setMyDS(javax.sql.DataSource ds) {this.myDS = ds; }
    @EJB(beanName=“AccountBean")
    private Account account;
    }

      在無狀態(tài)會話bean ServiceBean中,聲明了兩個依賴:一個是數(shù)據(jù)源,一個是業(yè)務(wù)接口。在運(yùn)行期間,EJB3.0容器一旦創(chuàng)建了ServiceBean的實例,就會分別通過方法注入和域注入將數(shù)據(jù)源對象和業(yè)務(wù)對象注入到ServiceBean中。

    3 截獲器

      3.1 基本概念

      作為EJB3.0中提出的新概念,截獲器是可以對bean的業(yè)務(wù)方法和生命周期事件進(jìn)行攔截的組件。截獲器需要由@Interceptors 或發(fā)布描述符文件中相關(guān)的標(biāo)簽指定。截獲器可以帶有狀態(tài)而且可以進(jìn)行依賴注入,其生命周期與其所綁定的EJB bean實例的生命周期一致。

      定義在截獲器中用于攔截目的的方法被稱為截獲器方法,其中,針對業(yè)務(wù)方法的截獲器方法通過@AroundInvoke標(biāo)注或發(fā)布描述符文件中相關(guān)的標(biāo)簽指定;針對生命周期回調(diào)的截獲器方法通過@PostConstruct, @PreDestroy等標(biāo)注或發(fā)布描述符文件中對應(yīng)的標(biāo)簽指定。

      截獲器分為四類:

        缺省截獲器:可作用于ejb-jar中定義的所有EJB bean。缺省截獲器只能定義在DD中,不存在相應(yīng)的標(biāo)注
        類級截獲器:只能作用于所指定的EJB bean
        方法級截獲器:只能作用于所指定的某個EJB bean業(yè)務(wù)方法,方法級截獲器不能用于攔截bean的生命周期事件
        bean 級截獲器:又被稱為自我截獲器,因為截獲器同時就是EJB bean本身,此時相關(guān)的截獲器方法只能作用于該EJB

      3.2 截獲器鏈的調(diào)用順序

      因為可以為EJB定義多個截獲器,所以存在截獲器鏈的調(diào)用順序問題,缺省情況下,以下原則被遵循:

        調(diào)用順序依次是缺省截獲器、類級截獲器、方法級截獲器以及bean級截獲器
        對于同類別的截獲器,按照聲明的順序調(diào)用
        總是優(yōu)先調(diào)用父類的截獲器方法。

      此外,EJB3.0規(guī)范還提供了更靈活的選項,詳細(xì)信息請參考EJB3.0規(guī)范中“截獲器”一節(jié):

        在發(fā)布描述符文件中設(shè)置“exclude-default-interceptors” 可以取消對缺省截獲器的調(diào)用,而應(yīng)用“exclude-class-interceptors”則取消對類級截獲器的調(diào)用
        為了替換缺省的截獲器鏈調(diào)用順序,可以設(shè)置發(fā)布描述符文件的“interceptor-order”。

      3.3 示例

    @Stateless(name="Trader")
    @Interceptors(ClassInterceptor.class)
    public class TraderBean implements Trader {
    @Interceptors(MethodInterceptor.class)
    public String sell(String stockSymbol) {

    }
    @AroundInvoke
    public Object selfInterceptor(InvocationContext) throws Exception {

    }
    }

      在無狀態(tài)會話bean TraderBean中,聲明了兩個截獲器:一個類級截獲器,一個方法級截獲器,此外,通過使用@AroundInvoke標(biāo)注,TraderBean的方法selfInterceptor被聲明為截獲器方法,所以TraderBean就是bean級截獲器。

    4 EJB3.0規(guī)范在依賴注入和截獲器方面的不足

      從依賴注入方面來說,EJB3.0目前支持的注入類型是非常有限的,諸如List、Map之類的集合類型都不能被注入。

      另一方面,EJB3.0的截獲器可被看作是一種AOP模型,截獲器類相當(dāng)于方面(Aspect),而截獲器方法相當(dāng)于通知(Advice),但這種AOP是非常簡單的:

        不支持引入(Introduction);
        不支持切入點(Pointcut)模式
        通過標(biāo)注告訴容器某個EJB需要使用截獲器,從而使得這種AOP模型具有一定的侵入性

    5 WebLogic Server 10 EJB3.0容器簡介

       5.1 Pitchfork 簡介

      Pitchfork是由Interface21與BEA合作開發(fā)的一個具有Apache License的開源項目,作為Spring的“增值”項目,開發(fā)Pitchfork有兩個目的:

        當(dāng)前應(yīng)用服務(wù)器可使用Pitchfork實現(xiàn)Java EE 5中的依賴注入,標(biāo)注處理以及EJB3.0中的截獲器。
        在Spring容器中支持Java EE 5的標(biāo)注

      5.2 WebLogic Server 10 EJB3.0容器的架構(gòu)

      WebLogic Server 10完全支持Java EE 5和EJB3.0,其EJB3.0 容器是基于Pitchfork來實現(xiàn)依賴注入與截獲器的,而Pitchfork又利用了Spring的依賴注入和AOP。此時,WebLogic Server 10的用戶有兩種選擇:

        使用EJB3.0標(biāo)準(zhǔn)模型: EJB bean實例由EJB容器創(chuàng)建,然后由Pitchfork實施Java EE 5 的依賴注入和截獲器,這是WebLogic Server 10的缺省配置。
        使用Spring擴(kuò)展模型:EJB bean實例由Spring容器創(chuàng)建并實施Spring的依賴注入,然后由Pitchfork實施Java EE 5的依賴注入,EJB3.0截獲器和Spring AOP。

    6 Spring擴(kuò)展模型

      6.1 使用Spring擴(kuò)展模型的主要開發(fā)步驟

        下載某個版本的Spring類庫(最好是由BEA指定的版本),至少需要包括以下jar文件:spring.jar, aspectjweaver.jar, commons-logging.jar, log4j-1.2.14.jar,如果需要,還可以增加其它jar文件。
        將這些jar文件加入到WebLogic Server 10的類路徑中。
        創(chuàng)建文本文件Weblogic.application.ComponentFacotry以標(biāo)識當(dāng)前應(yīng)用將使用Spring擴(kuò)展模型,其內(nèi)容只有一行:    Weblogic.application.SpringComponentFactory。
        創(chuàng)建/META-INF/services子目錄,然后放入前面創(chuàng)建的文件Weblogic.application.ComponentFacotry
        建立Spring 配置文件,并放入到/META-INF目錄下,如果是EJB應(yīng)用程序,Spring配置文件的名字應(yīng)該是spring-ejb-jar.xml,如果是Web應(yīng)用程序,Spring配置文件的名字則是spring-web.xml.
        為了使EJB bean能利用Spring的依賴注入與AOP,需要同時將其定義在spring-ejb-jar.xml(或spring-web.xml)中,從Spring角度來看,這就是一個普通的Spring bean,只不過它的id或name必須與對應(yīng)的EJB name相同。
        將上述目錄文件、相關(guān)的Java類、部署描述符等打包成標(biāo)準(zhǔn)的jar文件、war文件或ear文件。

      需要注意的是,在Spring配置文件中定義的bean,如果它也是一個EJB bean,則該Spring bean的class屬性會被忽略以避免潛在的沖突。

      6.2 示例

      示例一:利用Spring的依賴注入。本例將演示兩點,(1) 注入一個集合類型,(2) 注入一個Spring POJO對象

      (1) 開發(fā)一個bean類

    @Stateless(name="AccountManagementBean")
    @Remote({examples.AccountManagement.class})
    public class AccountManagementBean
    {
    private List accountList;
    private BusinessObject businessObject;
    public boolean doBusiness(String account) {
    if (accountList.contains(account)) {
    businessObject.doBusiness();
    return true;
    }
    return false;
    }
    public BusinessObject getBusinessObject() {
    return businessObject;
    }
    public void setBusinessObject(BusinessObject businessObject) {
    this.businessObject = businessObject;
    }

    public List getAccountList() {
    return accountList;
    }
    public void setAccountList(List accountList) {
    this.accountList = accountList;
    }
    }
      (2) 一個POJO

    public class BusinessObjectImpl implements BusinessObject
    {
    private String result;

    public void doBusiness() {
    System.out.println("I am doing business, the result is: " + result);
    }

    public String getResult() {
    return result;
    }

    public void setResult(String result) {
    this.result = result;
    }
    }
      (3) Spring-ejb-jar.xml


    <beans>
    <bean name="BusinessObject" class="examples.BusinessObjectImpl">
    <property name="result" value="success" />
    </bean>
    <bean id="AccountManagementBean">
    <property name="businessObject" ref="BusinessObject" />
    <property name="accountList">
    <list>
    <value>Safin</value>
    <value>Amy</value>
    <value>Albert</value>
    <value>Yang</value>
    </list>
    </property>
    </bean>
    </beans>

      示例二:利用Spring 的AOP。本例演示了混合使用JEE interceptor、基于代理的Spring AOP以及AspectJ的Aspect

      (1) 開發(fā)一個bean類

    @Stateless(name="AccountManagementBean")
    @Remote({examples.AccountManagement.class})
    public class AccountManagementBean
    {
    public AccountManagementBean() {}
    @Interceptors({examples.JEEInterceptor.class})
    public boolean doBusiness(String account) {
    System.out.println("I am doing business " + account);
    return true;
    }
    }

      (2) 開發(fā)一個JEE interceptor

    public class JEEInterceptor {
    @AroundInvoke
    private Object intercept(InvocationContext inv) throws Exception{
    System.out.println("I am in JEEInterceptor.intercept()");
    return inv.proceed();
    }
    }

      (3) 開發(fā)一個Advice

    public class SimpleAdvice implements MethodInterceptor{
    public Object invoke(MethodInvocation invocation) throws Throwable {
    System.out.println("I am in Spring AOP interceptor");
    return invocation.proceed();
    }
    }

      (4) 開發(fā)一個Pointcut

    public class SimpleStaticPointcut extends StaticMethodMatcherPointcut {
    public boolean matches(Method method, Class cls) {
    return "doBusiness".equals(method.getName());
    }
    public ClassFilter getClassFilter() {
    return new ClassFilter() {
    public boolean matches(Class cls) {
    return AccountManagementBean.class.isAssignableFrom(cls);
    }
    };
    }
    }

      (5) 開發(fā)一個AspectJ Aspect

    @Aspect
    public class Aspects {
    @Around("execution(* examples.AccountManagementBean.doBusiness(..))")
    public Object around(ProceedingJoinPoint pjp) {
    System.out.println(“I am in AspectJ aspect);
    Object retVal = null;
    try {
    retVal = pjp.proceed();
    } catch (Throwable e) {
    e.printStackTrace();
    }
    return retVal;
    }
    }

      (5) Spring-ejb-jar.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
    <bean id="AccountManagementBean" />
    <bean id="myAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
    <property name="advice">
    <bean class=”examples.SimpleAdvice” />
    </property>
    <property name="pointcut">
    <bean class="examples.SimpleStaticPointcut" />
    </property>
    </bean>
    <bean id="MyAspect" class="examples.Aspects" />
    </beans>

      6.3 優(yōu)點

      提供Spring擴(kuò)展模型具有如下好處:

        可以在同一個發(fā)布單元中混合使用EJB bean和Spring POJO,而且一個EJB bean可以同時是一個Spring POJO,因此被EJB容器和Spring容器同時管理
        有效地克服了EJB3.0 規(guī)范在依賴注入和截獲器方面的一些缺陷
        為用戶提供更靈活的選擇:
          如果標(biāo)準(zhǔn)的EJB 依賴注入以及截獲器可以滿足應(yīng)用需求,或者可移植性是優(yōu)先考慮的因素,則選用標(biāo)準(zhǔn)模型
          如果標(biāo)準(zhǔn)的EJB依賴注入以及截獲器不能滿足應(yīng)用需求,或者不用考慮可移植性,或者需要集成一些Spring應(yīng)用,則應(yīng)選用Spring擴(kuò)展模型

    7 Spring AOP在WebLogic Server 10 Spring擴(kuò)展模型中的使用限制及說明

      7.1 代理生成方式

      Spring AOP采用的是一種基于代理的框架,目前有兩種生成代理的方式:JDK動態(tài)代理和CGLIB。在WebLogic Server 10的Spring擴(kuò)展模型中,目前不支持CGLIB方式,這主要是因為生成的EJB類都是final的

      7.2 代理創(chuàng)建

      在Spring中,代理或者是通過諸如ProxyFactoryBean之類的工廠bean明確創(chuàng)建,或者是通過“自動代理”創(chuàng)建器隱含創(chuàng)建。

      在WebLogic Server 10中,Pitchfork已經(jīng)隱含提供了類似的“自動代理”機(jī)制,所以原有的Spring代理創(chuàng)建方式是無效的,換句話說,用戶只需要在Spring配置文件中定義目標(biāo)bean以及對應(yīng)的Spring Advisor和AspectJ Aspect, 不需要再定義ProxyFactoryBean和“自動代理”創(chuàng)建器,Pitchfork會自動為我們創(chuàng)建AOP代理

      7.3 截獲的順序問題

      在Spring擴(kuò)展模型中,可以混合使用JEE截獲器、Spring Advisor以及AspectJ Aspect,此時的調(diào)用順序為JEE截獲器、Spring Advisor以及AspectJ Aspect。

      7.4 bean的實例化模式

      缺省方式下,Spring bean是Singleton的,即Spring容器總是返回同一個bean實例,在Spring擴(kuò)展模型中,這意味著同一個Spring Advisor或AspectJ Aspect實例將被應(yīng)用到不同的EJB bean實例上,如果Advisor或Aspect實例是有狀態(tài)的,這可能會產(chǎn)生問題,為此我們推薦如下的使用方式:

       SLSB & MDB
        帶有狀態(tài)的Advisor或Aspect
         不推薦用帶有狀態(tài)的Advisor或Aspect,除非用戶意識到相關(guān)的后果并認(rèn)為這種后果是可以接收的,此時的實例化模式取決于具體應(yīng)用
        沒有狀態(tài)的Advisor或Aspect
         采用Singleton實例化模式
       SFSB
        帶有狀態(tài)的Advisor或Aspect
         正常情況下應(yīng)該采用的實例化模式是Prototype,除非用戶意識到采用Singletong的后果并認(rèn)為這種后果是可以接收的
        沒有狀態(tài)的Advisor或Aspect
         采用Singleton實例化模式

    8 結(jié)束語

      依賴注入和截獲器的引入,使得EJB3.0克服了很多EJB2.1的缺點,但與開源社區(qū)中流行的輕量級容器相比,EJB3.0無論是在依賴注入的范圍還是在AOP的易用性方面都還存在一定的不足。而最近BEA所推出的WebLogic Server 10不但完全支持EJB3.0,而且對其進(jìn)行了有效擴(kuò)展,這使得一方面可以充分利用在開源社區(qū)中出于領(lǐng)導(dǎo)地位的Spring在依賴注入和AOP方面的強(qiáng)大能力,另一方面又緊密依托WebLogic Server 10在事務(wù)、安全、集群方面領(lǐng)先的技術(shù),從而為EJB3.0用戶開發(fā)出易維護(hù)、可擴(kuò)展、高效率的企業(yè)應(yīng)用程序打下堅實的基礎(chǔ)。

    作者簡介

      李鋼 dev2devid: cc_masterli ,BEA研發(fā)中心WebLogic Server 研發(fā)團(tuán)隊成員,西安交通大學(xué)計算機(jī)專業(yè)博士,一直從事java中間件領(lǐng)域的研發(fā),2005年加入BEA,現(xiàn)為EJB3 中國研發(fā)小組的負(fù)責(zé)人。



    主站蜘蛛池模板: 亚洲精品在线免费看| 在线精品自拍亚洲第一区| 无人在线观看完整免费版视频| 亚洲国产av玩弄放荡人妇 | 5g影院5g天天爽永久免费影院| 国产人成亚洲第一网站在线播放| 亚洲&#228;v永久无码精品天堂久久| 国产免费AV片在线观看播放| 亚洲精品无码久久毛片波多野吉衣| 日韩免费无砖专区2020狼| 日本免费人成网ww555在线| 亚洲欧美国产欧美色欲| 久久精品国产精品亚洲精品| 成人免费视频软件网站| 特级做A爰片毛片免费看无码 | 亚洲成a人片7777| 亚洲中文无韩国r级电影| 国产卡一卡二卡三免费入口 | 久久综合国产乱子伦精品免费| 亚洲精品天堂成人片AV在线播放 | 搡女人真爽免费视频大全| 三上悠亚在线观看免费| 亚洲色在线无码国产精品不卡| 亚洲色无码一区二区三区| 国产在线19禁免费观看| 91高清免费国产自产拍2021| 国产福利电影一区二区三区,免费久久久久久久精| 精品亚洲成AV人在线观看| 国产亚洲精久久久久久无码77777| 精品熟女少妇AV免费观看| 免费精品无码AV片在线观看| 一级做a爰片性色毛片免费网站| 亚洲av日韩av综合| 久久久久亚洲AV成人片| 亚洲日韩精品射精日| jjzz亚洲亚洲女人| 高清国语自产拍免费视频国产| 国产免费不卡视频| 久久久久久毛片免费播放| a级毛片毛片免费观看久潮| 成人免费观看男女羞羞视频|