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

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

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

    和爪哇一起走過(guò)的日子

      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      12 隨筆 :: 0 文章 :: 6 評(píng)論 :: 0 Trackbacks
    AOP正在成為軟件開發(fā)的下一個(gè)圣杯。使用AOP,你可以將處理aspect的代碼注入主程序,通常主程序的主要目的并不在于處理這些aspect。AOP可以防止代碼混亂。
    為了理解AOP如何做到這點(diǎn),考慮一下記日志的工作。日志本身不太可能是你開發(fā)的主程序的主要任務(wù)。如果能將“不可見的”、通用的日志代碼注入主程序中,那該多好啊。AOP可以幫助你做到。
    Spring framework是很有前途的AOP技術(shù)。作為一種非侵略性的,輕型的AOP framework,你無(wú)需使用預(yù)編譯器或其他的元標(biāo)簽,便可以在Java程序中使用它。這意味著開發(fā)團(tuán)隊(duì)里只需一人要對(duì)付AOP framework,其他人還是象往常一樣編程。
    AOP是很多直覺難以理解的術(shù)語(yǔ)的根源。幸運(yùn)的是,你只要理解三個(gè)概念,就可以編寫AOP模塊。這三個(gè)概念是:advice,pointcut和advisor。advice是你想向別的程序內(nèi)部不同的地方注入的代碼。pointcut定義了需要注入advice的位置,通常是某個(gè)特定的類的一個(gè)public方法。advisor是pointcut和advice的裝配器,是將advice注入主程序中預(yù)定義位置的代碼。

    既然我們知道了需要使用advisor向主要代碼中注入“不可見的”advice,讓我們實(shí)現(xiàn)一個(gè)Spring AOP的例子。在這個(gè)例子中,我們將實(shí)現(xiàn)一個(gè)before advice,這意味著advice的代碼在被調(diào)用的public方法開始前被執(zhí)行。以下是這個(gè)before advice的實(shí)現(xiàn)代碼:

    代碼:
    package com.company.springaop.test;

    import java.lang.reflect.Method;
    import org.springframework.aop.MethodBeforeAdvice;

    public class TestBeforeAdvice implements MethodBeforeAdvice {

    public void before(Method m, Object[] args, Object target)
    throws Throwable {
    System.out.println("Hello world! (by "
    + this.getClass().getName()
    + ")");
    }
    }


    接口MethodBeforeAdvice只有一個(gè)方法before需要實(shí)現(xiàn),它定義了advice的實(shí)現(xiàn)。before方法共用三個(gè)參數(shù),它們提供了相當(dāng)豐富的信息。參數(shù)Method m是advice開始后執(zhí)行的方法。方法名稱可以用作判斷是否執(zhí)行代碼的條件。Object[] args是傳給被調(diào)用的public方法的參數(shù)數(shù)組。當(dāng)需要記日志時(shí),參數(shù)args和被執(zhí)行方法的名稱,都是非常有用的信息。你也可以改變傳給m的參數(shù),但要小心使用這個(gè)功能;編寫最初主程序的程序員并不知道主程序可能會(huì)和傳入?yún)?shù)的發(fā)生沖突。Object target是執(zhí)行方法m對(duì)象的引用。

    在下面的BeanImpl類中,每個(gè)public方法調(diào)用前,都會(huì)執(zhí)行advice:

    代碼:
    package com.company.springaop.test;

    public class BeanImpl implements Bean {

    public void theMethod() {
    System.out.println(this.getClass().getName()
    + "." + new Exception().getStackTrace()[0].getMethodName()
    + "()"
    + " says HELLO!");
    }
    }


    類BeanImpl實(shí)現(xiàn)了下面的接口Bean:

    代碼:
    package com.company.springaop.test;

    public interface Bean {
    public void theMethod();
    }

    雖然不是必須使用接口,但面向接口而不是面向?qū)崿F(xiàn)編程是良好的編程實(shí)踐,Spring也鼓勵(lì)這樣做。

    pointcut和advice通過(guò)配置文件來(lái)實(shí)現(xiàn),因此,接下來(lái)你只需編寫主方法的Java代碼:
    代碼:


    package com.company.springaop.test;

    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;

    public class Main {

    public static void main(String[] args) {
    //Read the configuration file
    ApplicationContext ctx
    = new FileSystemXmlApplicationContext("springconfig.xml");

    //Instantiate an object
    Bean x = (Bean) ctx.getBean("bean");

    //Execute the public method of the bean (the test)
    x.theMethod();
    }
    }

    我們從讀入和處理配置文件開始,接下來(lái)馬上要?jiǎng)?chuàng)建它。這個(gè)配置文件將作為粘合程序不同部分的“膠水”。讀入和處理配置文件后,我們會(huì)得到一個(gè)創(chuàng)建工廠ctx。任何一個(gè)Spring管理的對(duì)象都必須通過(guò)這個(gè)工廠來(lái)創(chuàng)建。對(duì)象通過(guò)工廠創(chuàng)建后便可正常使用。

    僅僅用配置文件便可把程序的每一部分組裝起來(lái)。
    代碼:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>
    <!--CONFIG-->
    <bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="proxyInterfaces">
    <value>com.company.springaop.test.Bean</value>
    </property>
    <property name="target">
    <ref local="beanTarget"/>
    </property>
    <property name="interceptorNames">
    <list>
    <value>theAdvisor</value>
    </list>
    </property>
    </bean>

    <!--CLASS-->
    <bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/>

    <!--ADVISOR-->
    <!--Note: An advisor assembles pointcut and advice-->
    <bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <property name="advice">
    <ref local="theBeforeAdvice"/>
    </property>
    <property name="pattern">
    <value>com\.company\.springaop\.test\.Bean\.theMethod</value>
    </property>
    </bean>

    <!--ADVICE-->
    <bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/>
    </beans>


    四個(gè)bean定義的次序并不重要。我們現(xiàn)在有了一個(gè)advice,一個(gè)包含了正則表達(dá)式pointcut的advisor,一個(gè)主程序類和一個(gè)配置好的接口,通過(guò)工廠ctx,這個(gè)接口返回自己本身實(shí)現(xiàn)的一個(gè)引用。

    BeanImpl和TestBeforeAdvice都是直接配置。我們用一個(gè)唯一的ID創(chuàng)建一個(gè)bean元素,并指定了一個(gè)實(shí)現(xiàn)類。這就是全部的工作。

    advisor通過(guò)Spring framework提供的一個(gè)RegexMethodPointcutAdvisor類來(lái)實(shí)現(xiàn)。我們用advisor的一個(gè)屬性來(lái)指定它所需的advice-bean。第二個(gè)屬性則用正則表達(dá)式定義了pointcut,確保良好的性能和易讀性。

    最后配置的是bean,它可以通過(guò)一個(gè)工廠來(lái)創(chuàng)建。bean的定義看起來(lái)比實(shí)際上要復(fù)雜。bean是ProxyFactoryBean的一個(gè)實(shí)現(xiàn),它是Spring framework的一部分。這個(gè)bean的行為通過(guò)一下的三個(gè)屬性來(lái)定義:


    屬性proxyInterface定義了接口類。

    屬性target指向本地配置的一個(gè)bean,這個(gè)bean返回一個(gè)接口的實(shí)現(xiàn)。

    屬性interceptorNames是唯一允許定義一個(gè)值列表的屬性。這個(gè)列表包含所有需要在beanTarget上執(zhí)行的advisor。注意,advisor列表的次序是非常重要的。

    Spring工具

    雖然你可以手工修改Ant構(gòu)建腳本,但使用SpringUI(譯注:SpringUI現(xiàn)在是Spring framework的一部分,并改名為spring-ide),使用Spring AOP變得很簡(jiǎn)單,只要點(diǎn)點(diǎn)鼠標(biāo)即可。你可以把SpringUI安裝成Eclipse的一個(gè)plug-in。然后,你只需在你的project上右擊鼠標(biāo),并選擇“add Spring Project Nature”。在project屬性中,你可以在“Spring Project”下添加Spring配置文件。在編譯前把下面的類庫(kù)加入project:aopalliance.jar,commons-logging.jar,jakarta-oro-2.0.7.jar和spring.jar。運(yùn)行程序時(shí)你會(huì)看到下面的信息:

    ... (logging information)
    Hello world! (by com.company.springaop.test.TestBeforeAdvice)
    com.company.springaop.test.BeanImpl.theMethod() says HELLO!


    優(yōu)點(diǎn)和缺點(diǎn)

    Spring比起其他的framework更有優(yōu)勢(shì),因?yàn)槌薃OP以外,它提供了更多別的功能。作為一個(gè)輕型framework,它在J2EE不同的部分都可以發(fā)揮作用。因此,即使不想使用Spring AOP,你可能還是想使用Spring。另一個(gè)優(yōu)點(diǎn)是,Spring并不要求開發(fā)團(tuán)隊(duì)所有的人員都會(huì)用它。學(xué)習(xí)Spring應(yīng)該從Spring reference的第一頁(yè)開始。讀了本文后,你應(yīng)該可以更好地理解Spring reference了。Spring唯一的缺點(diǎn)是缺乏更多的文檔,但它的mailing list是個(gè)很好的補(bǔ)充,而且會(huì)不斷地出現(xiàn)更多的文檔

    posted on 2005-10-14 09:05 撲撲 閱讀(2621) 評(píng)論(4)  編輯  收藏 所屬分類: Spring

    評(píng)論

    # re: Spring Aop簡(jiǎn)單實(shí)例入門 2005-10-14 09:12 撲撲
    昨晚重新翻出這篇看了看,打算把它用在這次項(xiàng)目的權(quán)限控制上.通過(guò)對(duì)service層方法做攔截,在攔截方法中對(duì)用戶的權(quán)限做判斷,最后確定是否繼續(xù)后續(xù)的操作.關(guān)天權(quán)限模型的實(shí)現(xiàn)還要參考ACL和RBAC.  回復(fù)  更多評(píng)論
      

    # re: Spring Aop簡(jiǎn)單實(shí)例入門 2006-07-26 18:14 智者無(wú)疆
    我用你的代碼做測(cè)試了,但只出現(xiàn)了com.company.springaop.test.BeanImpl.theMethod() says HELLO! ,而沒有出現(xiàn)Hello world! (by com.company.springaop.test.TestBeforeAdvice) ,請(qǐng)教這是為什么,有時(shí)間請(qǐng)指教指教??!我的QQ:280199080  回復(fù)  更多評(píng)論
      

    # re: Spring Aop簡(jiǎn)單實(shí)例入門 2006-12-05 17:26 剛調(diào)試過(guò)這個(gè)程序,調(diào)試不過(guò)
    出現(xiàn)異常
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bean' defined in file [D:\Eclipse\eclipse\workspace\testspring\src\springconf.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.FatalBeanException: Could not instantiate class [org.springframework.aop.framework.ProxyFactoryBean]; constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
    org.springframework.beans.FatalBeanException: Could not instantiate class [org.springframework.aop.framework.ProxyFactoryBean]; constructor threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
    java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;)Z
    at org.springframework.aop.framework.DefaultAopProxyFactory.<clinit>(DefaultAopProxyFactory.java:57)
    at org.springframework.aop.framework.ProxyConfig.<init>(ProxyConfig.java:72)
    at org.springframework.aop.framework.AdvisedSupport.<init>(AdvisedSupport.java:103)
    at org.springframework.aop.framework.ProxyFactoryBean.<init>(ProxyFactoryBean.java:88)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:274)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:172)
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:49)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:453)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:269)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:320)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:89)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:74)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:65)
    幫忙解決一下,3kq!
      回復(fù)  更多評(píng)論
      

    # re: Spring Aop簡(jiǎn)單實(shí)例入門 2012-07-16 16:28 yeahwell
    @撲撲
    兄弟,我最近剛好在和你做同樣的事。使用AOP攔截Service層的方法,來(lái)達(dá)到RBAC級(jí)別的權(quán)限控制,你實(shí)現(xiàn)了么,我遇到了一個(gè)問題、  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲精品欧洲精品| 亚洲人成小说网站色| 久久这里只精品99re免费| 久久久久久亚洲AV无码专区| 18禁超污无遮挡无码免费网站国产 | 精品成在人线AV无码免费看 | 亚洲日本在线免费观看| 五月天婷婷免费视频| 亚洲成A人片在线观看无码不卡| 美女视频黄频a免费观看| 永久免费av无码不卡在线观看| 日韩亚洲Av人人夜夜澡人人爽 | 亚洲va中文字幕无码| 久久免费高清视频| 亚洲色丰满少妇高潮18p| 夫妻免费无码V看片| 亚洲国产美女视频| 亚洲 综合 国产 欧洲 丝袜| 亚洲一区免费观看| 美女被爆羞羞网站在免费观看| 亚洲AV人无码综合在线观看| 国产乱子伦片免费观看中字| 免费看黄福利app导航看一下黄色录像| 全亚洲最新黄色特级网站 | 国产偷国产偷亚洲高清人| 亚洲韩国—中文字幕| 亚洲国产成人精品无码久久久久久综合 | 亚洲国产午夜中文字幕精品黄网站 | 国产成人综合亚洲| 亚洲高清美女一区二区三区| 18pao国产成视频永久免费| 羞羞漫画页面免费入口欢迎你| 久久久亚洲欧洲日产国码是AV| 无码欧精品亚洲日韩一区夜夜嗨 | 99精品视频在线观看免费| 久久青青成人亚洲精品| 国产精品视频免费观看| 久久国产精品免费| 黄色网址免费在线| 亚洲中文字幕乱码AV波多JI| 亚洲经典在线观看|