hk2000c技術(shù)專(zhuān)欄

          技術(shù)源于哲學(xué),哲學(xué)來(lái)源于生活 關(guān)心生活,關(guān)注健康,關(guān)心他人

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            111 隨筆 :: 1 文章 :: 28 評(píng)論 :: 0 Trackbacks

          #

          posted @ 2014-04-21 21:33 hk2000c 閱讀(188) | 評(píng)論 (0)編輯 收藏

          許多年以來(lái),對(duì)于軟件項(xiàng)目,企業(yè)軟件開(kāi)發(fā)的主流實(shí)踐一直都傾向于在單一的通用編程語(yǔ)言上進(jìn)行標(biāo)準(zhǔn)化,從而使得Java和C#成為今天編程語(yǔ)言的主流選擇。隨著越來(lái)越多的目光開(kāi)始投向DSL,也許我們的前腳已經(jīng)踏在了一道新的門(mén)檻之上,向前望去,我們會(huì)發(fā)現(xiàn)在軟件項(xiàng)目中采用多種語(yǔ)言已經(jīng)成為一個(gè)標(biāo)準(zhǔn),但80年代和90年代初出現(xiàn)的問(wèn)題不會(huì)重現(xiàn)。

          Martin Fowler提出,也許我們正在邁進(jìn)這樣的一個(gè)新時(shí)期

          [……]在這個(gè)時(shí)期內(nèi),我們將見(jiàn)證多種語(yǔ)言在同一個(gè)項(xiàng)目上的應(yīng)用,人們就像現(xiàn)在選擇框架一樣,根據(jù)功能來(lái)選擇相應(yīng)的語(yǔ)言。

          Fowler稱(chēng):“像Hibernate、Struts和ADO這樣的大型框架,給人們?cè)趯W(xué)習(xí)上帶來(lái)的挑戰(zhàn),絕不亞于學(xué)習(xí)一門(mén)語(yǔ)言,即便你在單一一門(mén)宿主語(yǔ)言上使用這些框架編程也是如此。”此外,在它們的宿主語(yǔ)言中表述需求的難度可能會(huì)相當(dāng)大,并可能引出笨拙難用的配置文件,“這些配置文件實(shí)際上就是使用XML寫(xiě)的外部領(lǐng)域特定語(yǔ)言”。

          在語(yǔ)言中嵌入DSL,而不是使用類(lèi)庫(kù),可能會(huì)是一個(gè)更為合適的解決方案。Martin給出了這樣的一個(gè)分析結(jié)論:“API就好比是在聲明一個(gè)詞匯表,而DSL則為其增加了相應(yīng)的語(yǔ)法,使得人們能夠?qū)懗鰲l理清晰的句子。”因此,使用DSL而不是框架會(huì)使代碼豐富表現(xiàn)力,為人們帶來(lái)“更良好的抽象處理方式”,并使“閱讀我們寫(xiě)出的代碼及對(duì)我們意圖的展示變得更加容易”。

          Piers Cawley稱(chēng),DSL的主要特性并非其可讀性,而是“它們對(duì)去相應(yīng)領(lǐng)域的高度專(zhuān)注”使得它們能夠更加明確地表義。Cawley為了闡述他的觀點(diǎn)舉了一個(gè)例子,說(shuō)明DSL不僅僅能讓我們“寫(xiě)出讀起來(lái)像領(lǐng)域?qū)<艺f(shuō)出來(lái)的話一樣的程序”,也可以很技術(shù)化,用來(lái)代表一個(gè)使用它們的語(yǔ)法進(jìn)行操控的框架。

          Neal Ford也相信,被他稱(chēng)為多語(yǔ)言編程(Polyglot Programming)的勢(shì)頭正在興起。在軟件開(kāi)發(fā)的這個(gè)新紀(jì)元中,日益明顯的主要特征就是嵌入更多的語(yǔ)言,使人們能夠“為所做的菜選擇一把恰到好處的刀,并且恰如其分地使用它”。他舉了一個(gè)例子,展示在Java編程語(yǔ)言中并行類(lèi)庫(kù)的使用難度,并將其與Haskell作比。Haskell是一門(mén)函數(shù)式語(yǔ)言,“消除了變量所帶來(lái)的副作用”,并使“編寫(xiě)線程安全的代碼”變得更容易。Ford強(qiáng)調(diào)說(shuō),Java和.NET平臺(tái)都存在Haskell語(yǔ)言的實(shí)現(xiàn)(Jaskell和Haskell.net)。

          不再使用單一語(yǔ)言進(jìn)行開(kāi)發(fā)所帶來(lái)的風(fēng)險(xiǎn)之一可能讓80年代末90年代初所出現(xiàn)的問(wèn)題又再次重現(xiàn),當(dāng)時(shí)語(yǔ)言就是完全獨(dú)立的平臺(tái),既不能互操作也不能放在一起良好地使用。Martin Fowler指出,現(xiàn)在的情況有這樣的一個(gè)重要區(qū)別:

          在80年代末期,人們很難讓各個(gè)語(yǔ)言之間緊密地互操作。這些年來(lái),人們花了很大精力創(chuàng)建出可以讓不同語(yǔ)言緊密共存的環(huán)境。腳本語(yǔ)言在傳統(tǒng)上與C語(yǔ)言有著很密切的關(guān)系。在JVM和CLR平臺(tái)上也有人為互操作花費(fèi)了大量精力。另外人們也在類(lèi)庫(kù)上投入了很多人力物力,為的是讓語(yǔ)言忽視類(lèi)庫(kù)的存在。

          最終,要學(xué)習(xí)并使用多種語(yǔ)言,對(duì)于業(yè)界乃至開(kāi)發(fā)人員都可能會(huì)變成一項(xiàng)重要資產(chǎn)。《Pragmatic Programmers》這本書(shū)里面就說(shuō)到,由于這樣做會(huì)對(duì)人們對(duì)編程的思考方式產(chǎn)生影響,因此這樣能幫助人們發(fā)現(xiàn)解決問(wèn)題的新途徑。

          您是怎樣認(rèn)為的呢?在下去的五年中,我們會(huì)開(kāi)始混合使用語(yǔ)言,并像用類(lèi)庫(kù)一樣頻繁地使用DSL嗎?

          posted @ 2011-11-10 05:56 hk2000c 閱讀(318) | 評(píng)論 (0)編輯 收藏

               摘要: java 裝載 groovy 方法  閱讀全文
          posted @ 2011-11-10 05:45 hk2000c 閱讀(745) | 評(píng)論 (0)編輯 收藏

               摘要: java 和groovy 集成

            閱讀全文
          posted @ 2011-11-10 05:37 hk2000c 閱讀(1064) | 評(píng)論 (0)編輯 收藏

          AspectJ

           

                AspectJ是一個(gè)面向切面的框架,它擴(kuò)展了Java語(yǔ)言。AspectJ定義了AOP語(yǔ)法所以它有一個(gè)專(zhuān)門(mén)的編譯器用來(lái)生成遵守Java字節(jié)編碼規(guī)范的Class文件


          一、AspectJ概述

          圖1 :FigureEditor例子的UML

                AspectJ(也就是AOP)的動(dòng)機(jī)是發(fā)現(xiàn)那些使用傳統(tǒng)的編程方法無(wú)法很好處理的問(wèn)題。考慮一個(gè)要在某些應(yīng)用中實(shí)施安全策略的問(wèn)題。安全性是貫穿于系統(tǒng)所有模塊間的問(wèn)題,每個(gè)模塊都需要應(yīng)用安全機(jī)制才能保證整個(gè)系統(tǒng)的安全性,很明顯這里的安全策略的實(shí)施問(wèn)題就是一個(gè)橫切關(guān)注點(diǎn),使用傳統(tǒng)的編程解決此問(wèn)題非常的困難而且容易產(chǎn)生差錯(cuò),這就正是AOP發(fā)揮作用的時(shí)候了。

                傳統(tǒng)的面向?qū)ο缶幊?/a>中,每個(gè)單元就是一個(gè)類(lèi),而類(lèi)似于安全性這方面的問(wèn)題,它們通常不能集中在一個(gè)類(lèi)中處理因?yàn)樗鼈儥M跨多個(gè)類(lèi),這就導(dǎo)致了代碼無(wú)法重用,可維護(hù)性差而且產(chǎn)生了大量代碼冗余,這是我們不愿意看到的。

                面向方面編程的出現(xiàn)正好給處于黑暗中的我們帶來(lái)了光明,它針對(duì)于這些橫切關(guān)注點(diǎn)進(jìn)行處理,就好象面向?qū)ο?/a>編程處理一般的關(guān)注點(diǎn)一樣。而作為AOP的具體實(shí)現(xiàn)之一的AspectJ,它向Java中加入了連接點(diǎn)(Join Point)這個(gè)新概念,其實(shí)它也只是現(xiàn)存的一個(gè)Java概念的名稱(chēng)而已。它向Java語(yǔ)言中加入少許新結(jié)構(gòu):切點(diǎn)(pointcut)、通知(Advice)、類(lèi)型間聲明(Inter-type declaration)和方面(Aspect)。切點(diǎn)和通知?jiǎng)討B(tài)地影響程序流程,類(lèi)型間聲明則是靜態(tài)的影響程序的類(lèi)等級(jí)結(jié)構(gòu),而方面則是對(duì)所有這些新結(jié)構(gòu)的封裝。

                一個(gè)連接點(diǎn)是程序流中指定的一點(diǎn)。切點(diǎn)收集特定的連接點(diǎn)集合和在這些點(diǎn)中的值。一個(gè)通知是當(dāng)一個(gè)連接點(diǎn)到達(dá)時(shí)執(zhí)行的代碼,這些都是AspectJ的動(dòng)態(tài)部分。其實(shí)連接點(diǎn)就好比是程序中的一條一條的語(yǔ)句,而切點(diǎn)就是特定一條語(yǔ)句處設(shè)置的一個(gè)斷點(diǎn),它收集了斷點(diǎn)處程序棧的信息,而通知就是在這個(gè)斷點(diǎn)前后想要加入的程序代碼。AspectJ中也有許多不同種類(lèi)的類(lèi)型間聲明,這就允許程序員修改程序的靜態(tài)結(jié)構(gòu)、名稱(chēng)、類(lèi)的成員以及類(lèi)之間的關(guān)系。AspectJ中的方面是橫切關(guān)注點(diǎn)的模塊單元。它們的行為與Java語(yǔ)言中的類(lèi)很象,但是方面還封裝了切點(diǎn)、通知以及類(lèi)型間聲明。

          動(dòng)態(tài)連接點(diǎn)模型

                任何面向方面編程的關(guān)鍵元素就是連接點(diǎn)模型。AspectJ提供了許多種類(lèi)的連接點(diǎn)集合,但是本篇只介紹它們中的一個(gè):方法調(diào)用連接點(diǎn)集(method call join points)。一個(gè)方法調(diào)用連接點(diǎn)捕捉對(duì)象的方法調(diào)用。每一個(gè)運(yùn)行時(shí)方法調(diào)用都是一個(gè)不同的連接點(diǎn),許多其他的連接點(diǎn)集合可能在方法調(diào)用連接點(diǎn)執(zhí)行時(shí)運(yùn),包括方法執(zhí)行時(shí)的所有連接點(diǎn)集合以及在方法中其他方法的調(diào)用。我們說(shuō)這些連接點(diǎn)集合在原來(lái)調(diào)用的連接點(diǎn)的動(dòng)態(tài)環(huán)境中執(zhí)行。

           

          切點(diǎn)

                 在AspectJ中,切點(diǎn)捕捉程序流中特定的連接點(diǎn)集合。例如,切點(diǎn)

                        call(void Point.setX(int))

          捕捉每一個(gè)簽名為void Point.setX(int)的方法調(diào)用的連接點(diǎn),也就是說(shuō),調(diào)用Point對(duì)象的有一個(gè)整型參數(shù)的void setX方法。切點(diǎn)能與其他切點(diǎn)通過(guò)或(||)、與(&&)以及非(!)操作符聯(lián)合。例如 call(void Point.setX(int)) || call(void Point.setY(int)) 捕捉setX或setY調(diào)用的連接點(diǎn)。切點(diǎn)還可以捕捉不同類(lèi)型的連接點(diǎn)集合,換句話說(shuō),它們能橫切類(lèi)型。例如

                 call(void FigureElement.setXY(int,int)) || call(void Point.setX(int))

                 || call(void Point.setY(int) || call(void Line.setP1(Point))

                 || call(void Line.setP2(Point));

          捕捉上述五個(gè)方法調(diào)用的任意一個(gè)的連接點(diǎn)集合。它在本文的例子中捕捉當(dāng)FigureElement移動(dòng)時(shí)的所有連接點(diǎn)集合。AspectJ使程序員可以命名一個(gè)切點(diǎn)集合,以便通知的使用。例如可以為上面的那些切點(diǎn)命名

          pointcut move():

          call(void FigureElement.setXY(int,int)) || call(void Point.setX(int))

          || call(void Point.setY(int)) || call(void Line.setP1(Point)) || call(void Line.setP2(Point));

          無(wú)論什么時(shí)候,程序員都可以使用move()代替捕捉這些復(fù)雜的切點(diǎn)。

                 前面所說(shuō)的切點(diǎn)都是基于顯示的方法簽名,它們稱(chēng)為基于名字(name-based)橫切。AspectJ還提供了另一種橫切,稱(chēng)為基于屬性(property-based)的橫切。它們可以使用通配符描述方法簽名,例如 call(void Figure.make*(..)) 捕捉Figure對(duì)象中以make開(kāi)頭的參數(shù)列表任意的方法調(diào)用的連接點(diǎn)。而 call(public & Figure.*(..)) 則捕捉Figure對(duì)象中的任何公共方法調(diào)用的連接點(diǎn)。但是通配符不是AspectJ支持的唯一屬性,AspectJ中還有許多其他的屬性可供程序員使用。例如cflow,它根據(jù)連接點(diǎn)集合是否在其他連接點(diǎn)集合的動(dòng)態(tài)環(huán)境中發(fā)生標(biāo)識(shí)連接點(diǎn)集合。例如 cflow(move()) 捕捉被move()捕捉到的連接點(diǎn)集合的動(dòng)態(tài)環(huán)境中發(fā)生的連接點(diǎn)。

           

          通知

                 雖然切點(diǎn)用來(lái)捕捉連接點(diǎn)集合,但是它們沒(méi)有做任何事。要真正實(shí)現(xiàn)橫切行為,我們需要使用通知機(jī)制。通知包含了切點(diǎn)和要在每個(gè)連連接點(diǎn)處執(zhí)行的代碼段。AspectJ有幾種通知。

          ·前通知(Before Advice)      當(dāng)?shù)竭_(dá)一個(gè)連接點(diǎn)但是在程序進(jìn)程運(yùn)行之前執(zhí)行。例如,前通知在方法實(shí)際調(diào)用之前運(yùn)行,剛剛在方法的參數(shù)被分析之后。

                 Before() : move(){ System.out.println(“物體將移動(dòng)了”);}

          ·后通知(After Advice) 當(dāng)特定連接點(diǎn)處的程序進(jìn)程執(zhí)行之后運(yùn)行。例如,一個(gè)方法調(diào)用的后通知在方法體運(yùn)行之后,剛好在控制返回調(diào)用者之前執(zhí)行。因?yàn)镴ava程序有兩種退出連接點(diǎn)的形式,正常的和拋出異常。相對(duì)的就有三種后通知:返回后通知(after returning)、拋出異常后通知(after throwing)和清楚的后通知(after),所謂清楚后通知就是指無(wú)論是正常還是異常都執(zhí)行的后通知,就像Java中的finally語(yǔ)句。

                 After() returning : move(){    System.out.println(“物體剛剛成功的移動(dòng)了”);}

          ·在周?chē)ㄖ?Around Advice)    在連接點(diǎn)到達(dá)后,顯示的控制程序進(jìn)程是否執(zhí)行(暫不討論)

           

          暴露切點(diǎn)環(huán)境

                 切點(diǎn)不僅僅捕捉連接點(diǎn),它還能暴露連接點(diǎn)處的部分執(zhí)行環(huán)境。切點(diǎn)中暴露的值可以在通知體中聲明以后使用。通知聲明有一個(gè)參數(shù)列表(和方法相同)用來(lái)描述它所使用的環(huán)境的名稱(chēng)。例如后通知

                 after(FigureElement fe,int x,int y) returning : somePointcuts {  someCodes  }

          使用了三個(gè)暴露的環(huán)境,一個(gè)名為fe的FigureElement對(duì)象,兩個(gè)整型變量x,y。通知體可以像使用方法的參數(shù)那樣使用這些變量,例如

                 after(FigureElement fe,int x,int y) returning : somePointcuts {

                        System.out.println(fe+”移動(dòng)到(”+x+”,”+y+”)”);

          }

          通知的切點(diǎn)發(fā)布了通知參數(shù)的值,三個(gè)原生切點(diǎn)this、target和args被用來(lái)發(fā)布這些值/所以上述例子的完整代碼為

                 after(FigureElement fe,int x,int y) returning : call(void FigureElement.setXY(int,int)

          && target(fe) && args(x,y) {

                        System.out.println(fe+”移動(dòng)到(”+x+”,”+y+”)”);

          }

          目標(biāo)對(duì)象是FigureElement所以fe是after的第一個(gè)參數(shù),調(diào)用的方法包含兩個(gè)整型參數(shù)所以x和y為after的第二和第三個(gè)參數(shù)。所以通知打印出方法setXY調(diào)用返回后對(duì)象移動(dòng)到的點(diǎn)x和y。當(dāng)然還可以使用命名切點(diǎn)完成同樣的工作,例如

                 pointcut setXY(FigureElement fe,int x,int y):call(void FigureElement.setXY(int,int)

                        && target(fe) && args(x,y);

                 after(FigureElement fe,int x,int y) returning : setXY(fe,x,y){

                 System.out.println(fe+”移動(dòng)到(”+x+”,”+y+”)”);

                 }

           

          類(lèi)型間聲明

                 AspectJ的類(lèi)型間聲明指的是那些跨越類(lèi)和它們的等級(jí)結(jié)構(gòu)的聲明。這些可能是橫跨多個(gè)類(lèi)的成員聲明或者是類(lèi)之間繼承關(guān)系的改變。不像通知是動(dòng)態(tài)地操作,類(lèi)型間聲明編譯時(shí)的靜態(tài)操作。考慮一下,Java語(yǔ)言中如何向一個(gè)一些的類(lèi)中加入新方法,這需要實(shí)現(xiàn)一個(gè)特定接口,所有類(lèi)都必須在各自?xún)?nèi)部實(shí)現(xiàn)接口聲明的方法,而使用AspectJ則可以將這些工作利用類(lèi)型間聲明放在一個(gè)方面中。這個(gè)方面聲明方法和字段,然后將它們與需要的類(lèi)聯(lián)系。

          假設(shè)我們想有一個(gè)Sreen對(duì)象觀察Point對(duì)象的變化,當(dāng)Point是一個(gè)存在的類(lèi)。我們可以通過(guò)書(shū)寫(xiě)一個(gè)方面,由這個(gè)方面聲明Point對(duì)象有一個(gè)實(shí)例字段observers,用來(lái)保存所有觀察Point對(duì)象的Screen對(duì)象的引用,從而實(shí)現(xiàn)這個(gè)功能。

                 Aspect PointObserving{

                        Private    Collection Point.observers=new ArrayList();

          ……

          }

          observers字段是私有字段,只有PointObserving能使用。因此,要在aspect中加入方法管理observers聚集。

                 Aspect PointObserving{

                        Private Collection Point.observers=new ArrayList();

                        Public static void addObserver(Point p,Screen s){

                               p.observers.add(s);

                        }

                        public static void removeObserver(Point p,Screen s){

                               p.observers.remove(s);

                        }

                        ……

          }

          然后我們可以定義一個(gè)切點(diǎn)stateChanges決定我們想要觀察什么并且提供一個(gè)after通知定義當(dāng)觀察到變化時(shí)我們想要做什么。

                 Aspect PointObserving{

                        Private Collection Point.observers=new ArrayList();

                        Public static void addObserver(Point p,Screen s){

                               p.observers.add(s);

                        }

                        public static void removeObserver(Point p,Screen s){

                               p.observers.remove(s);

                        }

                        pointcut stateChanges(Point p) : target(p) && call(void Point.set*(int));

                        after(Point p) : stateChanges(p){

                               Iterator it=p.observers.iterator();

                               While(it.hasNext()){

                                      UpdateObserver(p,(Screen)it.next()));

                               }

                        }

                        private static void updateObserver(Point p,Screen s){

                               s.display(p);

                        }

          }

          注意無(wú)論是Sreen還是Point的代碼都沒(méi)有被修改,所有的新功能的加入都在方面中實(shí)現(xiàn)了,很酷吧!

           

          方面

                 方面以橫切模塊單元的形式包裝了所有的切點(diǎn)、通知和類(lèi)型間聲明。這非常像Java語(yǔ)言的類(lèi)。實(shí)際上,方面也可以定義自己的方法,字段和初始化方法。像類(lèi)一樣一個(gè)方面也可以用abstrace關(guān)鍵字聲明為抽象方面,可以被子方面繼承。在AspectJ中方面的設(shè)計(jì)實(shí)際上使用了單例模式,缺省情況下,它不能使用new構(gòu)造,但是可以使用一個(gè)方法實(shí)例化例如方法aspectOf()可以獲得方面的實(shí)例。所以在方面的通知中可以使用非靜態(tài)的成員字段。

          例如

                 aspect Tracing {

                        OutputStream trace=System.out;

                        After() : move(){    trace.println(“物體成功移動(dòng)”); }


          二、AspectJ應(yīng)用范圍

                 如前所述,AspectJ可以用于應(yīng)用開(kāi)發(fā)的不同階段。下面討論不同階段的AspectJ的具體應(yīng)用情況。

          開(kāi)發(fā)型方面(Development Aspects)

                 開(kāi)發(fā)方面可以很容易的從真正的產(chǎn)品中刪除。而產(chǎn)品方面則被可用于開(kāi)發(fā)過(guò)程和生產(chǎn)過(guò)程,但是僅僅影響某幾個(gè)類(lèi)。

                 這一部分將通過(guò)幾個(gè)例子說(shuō)明方面在Java應(yīng)用的開(kāi)發(fā)階段是如何使用的。這些方面包括調(diào)試、測(cè)試和性能檢測(cè)等工作。方面定義的行為范圍包括簡(jiǎn)單的代碼跟蹤、測(cè)試應(yīng)用的內(nèi)在聯(lián)系等等。使用AspectJ不僅使得模塊化這些功能變?yōu)榭赡埽瑫r(shí)也使得根據(jù)需要打開(kāi)和關(guān)閉這些功能變成可能。

           

          代碼跟蹤(Tracing)
                 首先讓我們看看如何增加一個(gè)程序內(nèi)部工作的可視性。我們定義一個(gè)簡(jiǎn)單的方面用于代碼跟蹤并且在每個(gè)方法調(diào)用時(shí)輸出一些信息。在前一篇的圖形編輯例子中,這樣的方面可能僅僅簡(jiǎn)單的跟蹤什么時(shí)候畫(huà)一個(gè)點(diǎn)。

          aspect SimpleTracing {
              pointcut tracedCall():
                  call(void FigureElement.draw(GraphicsContext));
           
              before(): tracedCall() {
                  System.out.println("Entering: " + thisJoinPoint);
              }
          }
          代碼利用了thisJoinPoint變量。在所有的通知體內(nèi),這個(gè)變量將與描述當(dāng)前連接點(diǎn)的對(duì)象綁定。所以上述代碼在每次一個(gè)FigureElement對(duì)象接受到draw方法時(shí)輸出如下信息:

          Entering: call(void FigureElement.draw(GraphicsContext))

          通常我們?cè)谡{(diào)式程序時(shí),會(huì)在特定的地方放置幾條輸出語(yǔ)句,而當(dāng)調(diào)試結(jié)束時(shí)還需要找到這些代碼段將它們刪除,這樣做不但使我們的代碼很難看而且很費(fèi)時(shí)間。而使用AspectJ我們可以克服以上的兩個(gè)問(wèn)題,我們可以通過(guò)定義切點(diǎn)捕捉任何想要觀察的代碼段,利用通知可以在方面內(nèi)部書(shū)寫(xiě)輸出語(yǔ)句,而不需要修改源代碼,當(dāng)不在需要跟蹤語(yǔ)句的時(shí)候還可以很輕松的將方面從應(yīng)用中刪除并重新編譯代碼即可。

           

          前提條件和后續(xù)條件(Pre-and Post-Conditions)
                 許多的程序員使用按契約編程(Design by Contract)的形式。這種形式的編程需要顯式的前提條件測(cè)試以保證方法調(diào)用是否合適,還需要顯式的后續(xù)條件測(cè)試保證方法是否工作正常。AspectJ使得可以模塊化地實(shí)現(xiàn)這兩種條件測(cè)試。例如下面的代碼

          aspect PointBoundsChecking {

              pointcut setX(int x):

                  (call(void FigureElement.setXY(int, int)) && args(x, *))

                  || (call(void Point.setX(int)) && args(x));

           

              pointcut setY(int y):

                  (call(void FigureElement.setXY(int, int)) && args(*, y))

                  || (call(void Point.setY(int)) && args(y));

           

              before(int x): setX(x) {

                  if ( x < MIN_X || x > MAX_X )

                      throw new IllegalArgumentException("x is out of bounds.");

              }

           

              before(int y): setY(y) {

                  if ( y < MIN_Y || y > MAX_Y )

                      throw new IllegalArgumentException("y is out of bounds.");

              }

          }

          它實(shí)現(xiàn)了邊界檢測(cè)功能。當(dāng)FigureElement對(duì)象移動(dòng)時(shí),如果x或y的值超過(guò)了定義的邊界,程序?qū)?huì)拋出IllegalArgumentException異常。

           

          合同實(shí)施(Contract Enforcement)
                 基于屬性的橫切機(jī)制在定義更加復(fù)雜的合同實(shí)施上非常有用。一個(gè)十分強(qiáng)大的功能是它可以強(qiáng)制特定的方法調(diào)用只出現(xiàn)在對(duì)應(yīng)的程序中,而在其他程序中不出現(xiàn)。例如,下面的方面實(shí)施了一個(gè)限制,使得只有在知名的工廠方法中才能向注冊(cè)并添加FigureElement對(duì)象。實(shí)施這個(gè)限制的目的是為了確保沒(méi)有任何一個(gè)FigureElement對(duì)象被注冊(cè)多次。

          static aspect RegistrationProtection {

              pointcut register(): call(void Registry.register(FigureElement));

              pointcut canRegister(): withincode(static * FigureElement.make*(..));

           

              before(): register() && !canRegister() {

                  throw new IllegalAccessException("Illegal call " + thisJoinPoint);

              }

          }

          這個(gè)方面使用了withincode初始切點(diǎn),它表示在FigureElement對(duì)象的工廠方法(以make開(kāi)始的方法)體內(nèi)出現(xiàn)的所有連接點(diǎn)。在before通知中聲明一個(gè)異常,該通知用于捕捉任何不在工廠方法代碼內(nèi)部產(chǎn)生的register方法的調(diào)用。該通知在特定連接點(diǎn)處拋出一個(gè)運(yùn)行時(shí)異常,但是AspectJ能做地更好。使用declare error的形式,我們可以聲明一個(gè)編譯時(shí)的錯(cuò)誤。

          static aspect RegistrationProtection {

              pointcut register(): call(void Registry.register(FigureElement));

              pointcut canRegister(): withincode(static * FigureElement.make*(..));

           

              declare error: register() && !canRegister(): "Illegal call"

          }

          當(dāng)使用這個(gè)方面后,如果代碼中存在定義的這些非法調(diào)用我們將無(wú)法通過(guò)編譯。這種情況只出現(xiàn)在我們只需要靜態(tài)信息的時(shí)候,如果我們需要?jiǎng)討B(tài)信息,像上面提到的前提條件實(shí)施時(shí),就可以利用在通知中拋出帶參數(shù)的異常來(lái)實(shí)現(xiàn)。

           

          配置管理(Configuration Management)
                 AspectJ的配置管理可以使用類(lèi)似于make-file等技術(shù)進(jìn)行處理。程序員可以簡(jiǎn)單的包括他們想要的方面進(jìn)行編譯。不想要任何方面出現(xiàn)在產(chǎn)品階段的開(kāi)發(fā)者也可以通過(guò)配置他們的make-file使用傳統(tǒng)的Java編譯器編譯整個(gè)應(yīng)用。

           

          產(chǎn)品型方面(Production Aspects)

                 這一部分的方面例子將描述方面用于生產(chǎn)階段的應(yīng)用。產(chǎn)品方面將向應(yīng)用中加入功能而不僅僅為程序的內(nèi)部工作增加可視性。

          改變監(jiān)視(Change Monitoring)
                 在第一個(gè)例子,方面的角色是用于維護(hù)一位數(shù)據(jù)標(biāo)志,由它說(shuō)明對(duì)象從最后一次顯示刷新開(kāi)始是否移動(dòng)過(guò)。在方面中實(shí)現(xiàn)這樣的功能是十分直接的,testAndClear方法被顯示代碼調(diào)用以便找到一個(gè)圖形元素是否在最近移動(dòng)過(guò)。這個(gè)方法返回標(biāo)志的狀態(tài)并將它設(shè)置為假。切點(diǎn)move捕捉所有能夠是圖形移動(dòng)的方法調(diào)用。After通知截獲move切點(diǎn)并設(shè)置標(biāo)志位。

          aspect MoveTracking {

          private static boolean dirty = false;

           

              public static boolean testAndClear() {

                  boolean result = dirty;

                  dirty = false;

                  return result;

              }

           

              pointcut move():

                  call(void FigureElement.setXY(int, int)) ||

                  call(void Line.setP1(Point)) ||

                  call(void Line.setP2(Point)) ||

                  call(void Point.setX(int)) ||

                  call(void Point.setY(int));

           

              after() returning: move() {

                  dirty = true;

              }

          }
           

          這個(gè)簡(jiǎn)單例子同樣說(shuō)明了在產(chǎn)品代碼中使用AspectJ的一些好處。考慮使用普通的Java代碼實(shí)現(xiàn)這個(gè)功能:將有可能需要包含標(biāo)志位,testAndClear以及setFlag方法的輔助類(lèi)。這些方法需要每個(gè)移動(dòng)的圖形元素包含一個(gè)對(duì)setFlag方法的調(diào)用。這些方法的調(diào)用就是這個(gè)例子中的橫切關(guān)注點(diǎn)。

          ·顯示的捕捉了橫切關(guān)注點(diǎn)的結(jié)構(gòu)

          ·功能容易拔插

          ·實(shí)現(xiàn)更加穩(wěn)定

           

          傳遞上下文(Context Passing)
          橫切結(jié)構(gòu)的上下文傳遞在Java程序中是十分復(fù)雜的一部分。考慮實(shí)現(xiàn)一個(gè)功能,它允許客戶(hù)設(shè)置所創(chuàng)建的圖形對(duì)象的顏色。這個(gè)需求需要從客戶(hù)端傳入一個(gè)顏色或顏色工廠。而要在大量的方法中加入一個(gè)參數(shù),目的僅僅是為傳遞上下文信息這種不方便的情況是所有的程序員都十分熟悉的。

          使用AspectJ,這種上下文的傳遞可以使用模塊化的方式實(shí)現(xiàn)。下面代碼中的after通知僅當(dāng)一個(gè)圖形對(duì)象的工廠方法在客戶(hù)ColorControllingClient的某個(gè)方法控制流程中調(diào)用時(shí)才運(yùn)行。

          aspect ColorControl {

              pointcut CCClientCflow(ColorControllingClient client):

                  cflow(call(* * (..)) && target(client));

           

              pointcut make(): call(FigureElement Figure.make*(..));

           

              after (ColorControllingClient c) returning (FigureElement fe):

                      make() && CCClientCflow(c) {

                  fe.setColor(c.colorFor(fe));

              }

          }

          這個(gè)方面僅僅影響一小部分的方法,但是注意該功能的非AOP實(shí)現(xiàn)可能 需要編輯更多的方法。

           

          提供一致的行為(Providing Consistent Behavior)
          接下來(lái)的例子說(shuō)明了基于屬性的方面如何在很多操作中提供一致的處理功能。這個(gè)方面確保包c(diǎn)om.bigboxco的所有公共方法記錄由它們拋出的任何錯(cuò)誤。PublicMethodCall切點(diǎn)捕捉包中的公共方法調(diào)用, after通知在任何一個(gè)這種調(diào)用拋出錯(cuò)誤后運(yùn)行并且記錄下這個(gè)錯(cuò)誤。

          aspect PublicErrorLogging {

              Log log = new Log();

           

              pointcut publicMethodCall():

                  call(public * com.bigboxco.*.*(..));

           

              after() throwing (Error e): publicMethodCall() {

                  log.write(e);

              }

          }

          在一些情況中,這個(gè)方面可以記錄一個(gè)異常兩次。這在com.bigboxco包內(nèi)部的代碼自己調(diào)用本包中的公共方法時(shí)發(fā)生。為解決這個(gè)問(wèn)題,我們可以使用cflow初始切點(diǎn)將這些內(nèi)部調(diào)用排除:

          after() throwing (Error e) : publicMethodCall() && !cflow(publicMethodCall()) {

              log.write(e);

          }

           

          結(jié)論

                 AspectJ是對(duì)Java語(yǔ)言的簡(jiǎn)單而且實(shí)際的面向方面的擴(kuò)展。僅通過(guò)加入幾個(gè)新結(jié)構(gòu),AspectJ提供了對(duì)模塊化實(shí)現(xiàn)各種橫切關(guān)注點(diǎn)的有力支持。向以有的Java開(kāi)發(fā)項(xiàng)目中加入AspectJ是一個(gè)直接而且漸增的任務(wù)。一條路徑就是通過(guò)從使用開(kāi)發(fā)方面開(kāi)始再到產(chǎn)品方面當(dāng)擁有了AspectJ的經(jīng)驗(yàn)后就使用開(kāi)發(fā)可重用方面。當(dāng)然可以選取其他的開(kāi)發(fā)路徑。例如,一些開(kāi)發(fā)者將從使用產(chǎn)品方面馬上得到好處,另外的人員可能馬上編寫(xiě)可重用的方面。

                 AspectJ可以使用基于名字和基于屬性這兩種橫切點(diǎn)。使用基于名字橫切點(diǎn)的方面僅影響少數(shù)幾個(gè)類(lèi),雖然它們是小范圍的,但是比起普通的Java實(shí)現(xiàn)來(lái)說(shuō)它們能夠減少大量的復(fù)雜度。使用基于屬性橫切點(diǎn)的方面可以有小范圍或著大范圍。使用AspectJ導(dǎo)致了橫切關(guān)注點(diǎn)的干凈、模塊化的實(shí)現(xiàn)。當(dāng)編寫(xiě)AspectJ方面時(shí),橫切關(guān)注點(diǎn)的結(jié)構(gòu)變得十分明顯和易懂。方面也是高度模塊化的,使得開(kāi)發(fā)可拔插的橫切功能變成現(xiàn)實(shí)。

                 AspectJ提供了比這兩部分簡(jiǎn)短介紹更多的功能。本系列的下一章內(nèi)容,The AspectJ Language,將介紹 AspectJ語(yǔ)言的更多細(xì)節(jié)和特征。系列的第三章,Examples將通過(guò)一些完整的例子說(shuō)明如何使用AspectJ。建議大家在仔細(xì)閱讀了接下來(lái)的兩章后再?zèng)Q定是否在項(xiàng)目中加入AspectJ。


          三、AspectJ的高級(jí)特性

          (一)、The reflection API

          說(shuō)到高級(jí)特性,首先要說(shuō)的就是AspectJ提供的一套reflection API,主要包括JoinPoint、JoinPoint.StaticPart和Signature三個(gè)主要的接口。你可以從aspectj.jar中的javadoc來(lái)了解它們的詳細(xì)情況。那它們能提供什么功能呢?其實(shí)從字面上就能大致明白:通過(guò)這三個(gè)接口能訪問(wèn)到Join Points的信息。譬如,調(diào)用thisJoinPoint.getArgs()就可以得到方法的參數(shù)列表。

          (二)、Aspect precedence

          在AspectJ中,pointcut和advice都會(huì)包含在一個(gè)aspect中。在應(yīng)用系統(tǒng)中,對(duì)同一個(gè)join point會(huì)有多種advice(logging,caching等),這就會(huì)引出一個(gè)問(wèn)題:如果系統(tǒng)中有很多的aspect,而這些aspect很有可能會(huì)捕獲同樣的join points,那這些aspect的執(zhí)行順序是如何安排的呢?

          AspectJ早已為我們考慮到了這個(gè)問(wèn)題,它提供了一種設(shè)置aspect precedence的方法。對(duì)三種不同的advice來(lái)說(shuō):

          1、before advice是先執(zhí)行higher-precedence,后執(zhí)行l(wèi)ower-precedence;

          2、around advice是higher-precedence包含lower-precedence,當(dāng)higher-precedence around advice沒(méi)有調(diào)用proceed()方法時(shí),lower-precedence不會(huì)被執(zhí)行;

          3、after advice與before advice正好相反,先執(zhí)行執(zhí)行l(wèi)ower-precedence,然后執(zhí)行higher-precedence。

          那應(yīng)該如何來(lái)聲明aspect precedence?非常簡(jiǎn)單,只要在aspect中使用如下的語(yǔ)法即可:

          declare precedence : TypePattern1, TypePattern2, ..;

          從左往右,排在前面的是higher-precedence advice,后面的是lower-precedence。

          (三)、Aspect association

          在Java中,為了節(jié)省對(duì)象每次構(gòu)建的耗費(fèi),增加效率,很多人會(huì)考慮使用Singleton模式,讓jvm中只有一個(gè)實(shí)例存在。AspectJ當(dāng)然為我們考慮到這個(gè)問(wèn)題,Aspect association實(shí)際上就是aspect與advised join point object的一種關(guān)聯(lián)關(guān)系,這很類(lèi)似于OO中association,譬如1:1,1:m等。Aspect association能讓我們能更好地控制aspect的狀態(tài)信息。

          在AspectJ中可以把Aspect association大致分為三類(lèi):

          1、Per virtual machine (default)

          一個(gè)jvm中只有一個(gè)aspect instance,AspectJ默認(rèn)association。

          2、Per object

          每一個(gè)advised join point object都會(huì)產(chǎn)生一個(gè)aspect instance,不過(guò)同一個(gè)object instance只會(huì)產(chǎn)生一個(gè)aspect instance。

          3、Per control-flow association

          這種association稍微復(fù)雜一些,它主要針對(duì)程序調(diào)用的控制流,譬如:A方法調(diào)用B方法,B方法又調(diào)用C方法,這就是control-flow。

          在aspect中聲明這三種association非常簡(jiǎn)單,它的主要語(yǔ)法如下:

          aspect [( )] {
          ... aspect body
          }

          Per virtual machine是aspectj的默認(rèn)association,不需要你額外的聲明,正常使用即可。

          Per object主要有兩種方式:perthis()和pertarget()。perthis()主要用于execution object,pertarget()主要用于target object,兩者非常類(lèi)似。

          Per control-flow中也包含兩種方式:percflow()和percflowbelow()。這兩者也很類(lèi)似,只是兩者的control-flow不太一樣而已。

          維護(hù)aspect的狀態(tài)信息還有一種方法,就是使用introduce。可以在aspect中introduce member fields,通過(guò)fields來(lái)保存狀態(tài)信息。

           

          四、AspectJ實(shí)例

           

          使用方面的Tracing程序

                 寫(xiě)一個(gè)具有跟蹤能力的類(lèi)是很簡(jiǎn)單的事情:一組方法,一個(gè)控制其開(kāi)或關(guān)的布爾變量,一種可選的輸出流,可能還有一些格式化輸出能力。這些都是Trace類(lèi)需要的東西。當(dāng)然,如果程序需要的話,Trace類(lèi)也可以實(shí)現(xiàn)的十分的復(fù)雜。開(kāi)發(fā)這樣的程序只是一方面,更重要的是如何在合適的時(shí)候調(diào)用它。在大型系統(tǒng)開(kāi)發(fā)過(guò)程中,跟蹤程序往往影響效率,而且在正式版本中去除這些功能十分麻煩,需要修改任何包含跟蹤代碼的源碼。出于這些原因,開(kāi)發(fā)人員常常使用腳本程序以便向源碼中添加或刪除跟蹤代碼。

                 AspectJ可以更加方便的實(shí)現(xiàn)跟蹤功能并克服這些缺點(diǎn)。Tracing可以看作是面向整個(gè)系統(tǒng)的關(guān)注點(diǎn),因此,Tracing方面可以完全獨(dú)立在系統(tǒng)之外并且在不影響系統(tǒng)基本功能的情況下嵌入系統(tǒng)。

           

          應(yīng)用實(shí)例

          整個(gè)例子只有四個(gè)類(lèi)。應(yīng)用是關(guān)于Shape的。TwoShape類(lèi)是Shape類(lèi)等級(jí)的基類(lèi)。

          public abstract class TwoDShape {

              protected double x, y;

              protected TwoDShape(double x, double y) {

                  this.x = x; this.y = y;

              }

              public double getX() { return x; }

              public double getY() { return y; }

              public double distance(TwoDShape s) {

                  double dx = Math.abs(s.getX() - x);

                  double dy = Math.abs(s.getY() - y);

                  return Math.sqrt(dx*dx + dy*dy);

              }

              public abstract double perimeter();

              public abstract double area();

              public String toString() {

                  return (" @ (" + String.valueOf(x) + ", " + String.valueOf(y) + ") ");

              }

          }

          TwoShape類(lèi)有兩個(gè)子類(lèi),Circle和Square  

          public class Circle extends TwoDShape {

              protected double r;

              public Circle(double x, double y, double r) {

                  super(x, y); this.r = r;

              }

              public Circle(double x, double y) { this(  x,   y, 1.0); }

              public Circle(double r)           { this(0.0, 0.0,   r); }

              public Circle()                   { this(0.0, 0.0, 1.0); }

              public double perimeter() {

                  return 2 * Math.PI * r;

              }

              public double area() {

                  return Math.PI * r*r;

              }

              public String toString() {

                  return ("Circle radius = " + String.valueOf(r) + super.toString());

              }

          }

          public class Square extends TwoDShape {

              protected double s;    // side

              public Square(double x, double y, double s) {

                  super(x, y); this.s = s;

              }

              public Square(double x, double y) { this(  x,   y, 1.0); }

              public Square(double s)           { this(0.0, 0.0,   s); }

              public Square()                   { this(0.0, 0.0, 1.0); }

              public double perimeter() {

                  return 4 * s;

              }

              public double area() {

                  return s*s;

              }

              public String toString() {

                  return ("Square side = " + String.valueOf(s) + super.toString());

              }

          }

           

          Tracing版本一

          首先我們直接實(shí)現(xiàn)一個(gè)Trace類(lèi)并不使用方面。公共接口Trace.java

          public class Trace {

              public static int TRACELEVEL = 0;

              public static void initStream(PrintStream s) {...}

              public static void traceEntry(String str) {...}

              public static void traceExit(String str) {...}

          }

          如果我們沒(méi)有AspectJ,我們需要在所有需要跟蹤的方法或構(gòu)造子中直接調(diào)用traceEntry和traceExit方法并且初試化TRACELEVEL和輸出流。以上面的例子來(lái)說(shuō),如果我們要跟蹤所有的方法調(diào)用(包括構(gòu)造子)則需要40次的方法調(diào)用并且還要時(shí)刻注意沒(méi)有漏掉什么方法,但是使用方面我們可以一致而可靠的完成。TraceMyClasses.java

          aspect TraceMyClasses {

              pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);

              pointcut myConstructor(): myClass() && execution(new(..));

              pointcut myMethod(): myClass() && execution(* *(..));

           

              before (): myConstructor() {

                  Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());

              }

              after(): myConstructor() {

                  Trace.traceExit("" + thisJoinPointStaticPart.getSignature());

              }

           

              before (): myMethod() {

                  Trace.traceEntry("" + thisJoinPointStaticPart.getSignature());

              }

              after(): myMethod() {

                  Trace.traceExit("" + thisJoinPointStaticPart.getSignature());

              }

          }

          這個(gè)方面在合適的時(shí)候調(diào)用了跟蹤方法。根據(jù)此方面,跟蹤方法在Shape等級(jí)中每個(gè)方法或構(gòu)造子的入口和出口處調(diào)用,輸出的是各個(gè)方法的簽名。因?yàn)榉椒ê灻庆o態(tài)信息,我們可以利用thisJoinPointStaticPart對(duì)象獲得。運(yùn)行這個(gè)方面的main方法可以獲得以下輸出:

            --> tracing.TwoDShape(double, double)

            <-- tracing.TwoDShape(double, double)

            --> tracing.Circle(double, double, double)

            <-- tracing.Circle(double, double, double)

            --> tracing.TwoDShape(double, double)

            <-- tracing.TwoDShape(double, double)

            --> tracing.Circle(double, double, double)

            <-- tracing.Circle(double, double, double)

            --> tracing.Circle(double)

            <-- tracing.Circle(double)

            --> tracing.TwoDShape(double, double)

            <-- tracing.TwoDShape(double, double)

            --> tracing.Square(double, double, double)

            <-- tracing.Square(double, double, double)

            --> tracing.Square(double, double)

            <-- tracing.Square(double, double)

            --> double tracing.Circle.perimeter()

            <-- double tracing.Circle.perimeter()

          c1.perimeter() = 12.566370614359172

            --> double tracing.Circle.area()

            <-- double tracing.Circle.area()

          c1.area() = 12.566370614359172

            --> double tracing.Square.perimeter()

            <-- double tracing.Square.perimeter()

          s1.perimeter() = 4.0

            --> double tracing.Square.area()

            <-- double tracing.Square.area()

          s1.area() = 1.0

            --> double tracing.TwoDShape.distance(TwoDShape)

              --> double tracing.TwoDShape.getX()

              <-- double tracing.TwoDShape.getX()

              --> double tracing.TwoDShape.getY()

              <-- double tracing.TwoDShape.getY()

            <-- double tracing.TwoDShape.distance(TwoDShape)

          c2.distance(c1) = 4.242640687119285

            --> double tracing.TwoDShape.distance(TwoDShape)

              --> double tracing.TwoDShape.getX()

              <-- double tracing.TwoDShape.getX()

              --> double tracing.TwoDShape.getY()

              <-- double tracing.TwoDShape.getY()

            <-- double tracing.TwoDShape.distance(TwoDShape)

          s1.distance(c1) = 2.23606797749979

            --> String tracing.Square.toString()

              --> String tracing.TwoDShape.toString()

              <-- String tracing.TwoDShape.toString()

            <-- String tracing.Square.toString()

          s1.toString(): Square side = 1.0 @ (1.0, 2.0)

           

          Tracing版本二

                 版本二實(shí)現(xiàn)了可重用的tracing方面,使其不僅僅用于Shape的例子。首先定義如下的抽象方面Trace.java

          abstract aspect Trace {

           

              public static int TRACELEVEL = 2;

              public static void initStream(PrintStream s) {...}

              protected static void traceEntry(String str) {...}

              protected static void traceExit(String str) {...}

          abstract pointcut myClass();

           

          }

          為了使用它,我們需要定義我們自己的子類(lèi)。

          public aspect TraceMyClasses extends Trace {

              pointcut myClass(): within(TwoDShape) || within(Circle) || within(Square);

           

              public static void main(String[] args) {

                  Trace.TRACELEVEL = 2;

                  Trace.initStream(System.err);

                  ExampleMain.main(args);

              }

          }

          注意我們僅僅在類(lèi)中聲明了一個(gè)切點(diǎn),它是超類(lèi)中聲明的抽象切點(diǎn)的具體實(shí)現(xiàn)。版本二的Trace類(lèi)的完整實(shí)現(xiàn)如下

          abstract aspect Trace {

           

              // implementation part

           

              public static int TRACELEVEL = 2;

              protected static PrintStream stream = System.err;

              protected static int callDepth = 0;

           

              public static void initStream(PrintStream s) {

                  stream = s;

              }

              protected static void traceEntry(String str) {

                  if (TRACELEVEL == 0) return;

                  if (TRACELEVEL == 2) callDepth++;

                  printEntering(str);

              }

              protected static void traceExit(String str) {

                  if (TRACELEVEL == 0) return;

                  printExiting(str);

                  if (TRACELEVEL == 2) callDepth--;

              }

              private static void printEntering(String str) {

                  printIndent();

                  stream.println("--> " + str);

              }

              private static void printExiting(String str) {

                  printIndent();

                  stream.println("<-- " + str);

              }

              private static void printIndent() {

                  for (int i = 0; i < callDepth; i++)

                      stream.print("  ");

              }

           

              // protocol part

           

              abstract pointcut myClass();

           

              pointcut myConstructor(): myClass() && execution(new(..));

              pointcut myMethod(): myClass() && execution(* *(..));

           

              before(): myConstructor() {

                  traceEntry("" + thisJoinPointStaticPart.getSignature());

              }

              after(): myConstructor() {

                  traceExit("" + thisJoinPointStaticPart.getSignature());

              }

           

              before(): myMethod() {

                  traceEntry("" + thisJoinPointStaticPart.getSignature());

              }

              after(): myMethod() {

                  traceExit("" + thisJoinPointStaticPart.getSignature());

              }

          }

          它與版本一的不同包括幾個(gè)部分。首先在版本一中Trace用單獨(dú)的類(lèi)來(lái)實(shí)現(xiàn)而方面是針對(duì)特定應(yīng)用實(shí)現(xiàn)的,而版本二則將Trace所需的方法和切點(diǎn)定義融合在一個(gè)抽象方面中。這樣做的結(jié)果是traceEntry和traceExit方法不需要看作是公共方法,它們將由方面內(nèi)部的通知調(diào)用,客戶(hù)完全不需要知道它們的存在。這個(gè)方面的一個(gè)關(guān)鍵點(diǎn)是使用了抽象切點(diǎn),它其實(shí)與抽象方法類(lèi)似,它并不提供具體實(shí)現(xiàn)而是由子方面實(shí)現(xiàn)它。

           

          Tracing版本三

                 在前一版本中,我們將traceEntry和traceExit方法隱藏在方面內(nèi)部,這樣做的好處是我們可以方便的更改接口而不影響余下的代碼。

                 重新考慮不使用AspectJ的程序。假設(shè),一段時(shí)間以后,tracing的需求變了,我們需要在輸出中加入方法所屬對(duì)象的信息。至少有兩種方法實(shí)現(xiàn),一是保持traceEntry和traceExit方法不變,那么調(diào)用者有責(zé)任處理顯示對(duì)象的邏輯,代碼可能如下

                 Trace.traceEntry("Square.distance in " + toString());

          另一種方法是增強(qiáng)方法的功能,添加一個(gè)參數(shù)表示對(duì)象,例如

            public static void traceEntry(String str, Object obj);

            public static void traceExit(String str, Object obj);

          然而客戶(hù)仍然有責(zé)任傳遞正確的對(duì)象,調(diào)用代碼如下

                 Trace.traceEntry("Square.distance", this);

          這兩種方法都需要?jiǎng)討B(tài)改變其余代碼,每個(gè)對(duì)traceEntry和traceExit方法的調(diào)用都需要改變。

                 這里體現(xiàn)了方面實(shí)現(xiàn)的另一個(gè)好處,在版本二的實(shí)現(xiàn)中,我們只需要改變Trace方面內(nèi)部的一小部分代碼,下面是版本三的Trace方面實(shí)現(xiàn)

          abstract aspect Trace {

           

              public static int TRACELEVEL = 0;

              protected static PrintStream stream = null;

              protected static int callDepth = 0;

           

              public static void initStream(PrintStream s) {

                  stream = s;

              }

           

              protected static void traceEntry(String str, Object o) {

                  if (TRACELEVEL == 0) return;

                  if (TRACELEVEL == 2) callDepth++;

                  printEntering(str + ": " + o.toString());

              }

           

              protected static void traceExit(String str, Object o) {

                  if (TRACELEVEL == 0) return;

                  printExiting(str + ": " + o.toString());

                  if (TRACELEVEL == 2) callDepth--;

              }

           

              private static void printEntering(String str) {

                  printIndent();

                  stream.println("Entering " + str);

              }

           

              private static void printExiting(String str) {

                  printIndent();

                  stream.println("Exiting " + str);

              }

           

              private static void printIndent() {

                  for (int i = 0; i < callDepth; i++)

                      stream.print("  ");

              }

           

              abstract pointcut myClass(Object obj);

           

              pointcut myConstructor(Object obj): myClass(obj) && execution(new(..));

              pointcut myMethod(Object obj): myClass(obj) &&

                  execution(* *(..)) && !execution(String toString());

           

              before(Object obj): myConstructor(obj) {

                  traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);

              }

              after(Object obj): myConstructor(obj) {

                  traceExit("" + thisJoinPointStaticPart.getSignature(), obj);

              }

           

              before(Object obj): myMethod(obj) {

                  traceEntry("" + thisJoinPointStaticPart.getSignature(), obj);

              }

              after(Object obj): myMethod(obj) {

                  traceExit("" + thisJoinPointStaticPart.getSignature(), obj);

              }

          }

          在此我們必須在methods切點(diǎn)排除toString方法的執(zhí)行。問(wèn)題是toString方法在通知內(nèi)部調(diào)用,因此如果我們跟蹤它,我們將陷入無(wú)限循環(huán)中。這一點(diǎn)不明顯,所以必須在寫(xiě)通知時(shí)格外注意。如果通知回調(diào)對(duì)象,通常都回存在循環(huán)的可能性。

                 事實(shí)上,簡(jiǎn)單的排除連接點(diǎn)的執(zhí)行并不夠,如果在這之中調(diào)用了其他跟蹤方法,那么就必須提供以下限制

          && !cflow(execution(String toString()))

          排除toString方法的執(zhí)行以及在這之下的所有連接點(diǎn)。

                 總之,為了實(shí)現(xiàn)需求的改變我們必須在Trace方面中做一些改變,包括切點(diǎn)說(shuō)明。但是實(shí)現(xiàn)的改變只局限于Trace方面內(nèi)部,而如果沒(méi)有方面,則需要更改每個(gè)應(yīng)用類(lèi)的實(shí)現(xiàn)。
          (來(lái)源:http://befresh.blogbus.com/logs/2004/08/339330.html;
          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=15565)

           

           

          posted @ 2008-10-25 00:08 hk2000c 閱讀(944) | 評(píng)論 (2)編輯 收藏

          .概述

          1.1 JMS與ActiveMQ特性  

             JMS始終在JavaEE五花八門(mén)的協(xié)議里,WebService滿天飛的時(shí)候占一位置,是因?yàn)椋?/p>

          • 它可以把不影響用戶(hù)執(zhí)行結(jié)果又比較耗時(shí)的任務(wù)(比如發(fā)郵件通知管理員)異步的扔給JMS 服務(wù)端去做,而盡快的把屏幕返還給用戶(hù)。
          • 服務(wù)端能夠多線程排隊(duì)響應(yīng)高并發(fā)的請(qǐng)求,并保證請(qǐng)求不丟失。
          • 可以在Java世界里達(dá)到最高的解耦。客戶(hù)端與服務(wù)端無(wú)需直連,甚至無(wú)需知曉對(duì)方是誰(shuí)、在哪里、有多少人,只要對(duì)流過(guò)的信息作響應(yīng)就行了,在企業(yè)應(yīng)用環(huán)境復(fù)雜時(shí)作用明顯。

              ActiveMQ的特性:

          • 完全支持JMS1.1和J2EE 1.4規(guī)范的 JMS Provider實(shí)現(xiàn),也是Apache Geronimo默認(rèn)的JMS provider。
          • POJO withdout EJB Container,不需要實(shí)現(xiàn)EJB繁瑣復(fù)雜的Message Bean接口和配置。
          • Spring Base,可以使用Spring的各種特性如IOC、AOP 。
          • Effective,基于Jencks的JCA Container實(shí)現(xiàn) pool connection,control transactions and manage security。 

          1.2 SpringSide 的完全POJO的JMS方案   

            SpringSide 2.0在BookStore示例中,演示了用戶(hù)下訂單時(shí),將發(fā)通知信到用戶(hù)郵箱的動(dòng)作,通過(guò)JMS交給JMS服務(wù)端異步完成,避免了郵件服務(wù)器的堵塞而影響用戶(hù)的下訂。

            全部代碼于examples\bookstore\src\java\org\springside\bookstore\components\activemq 目錄中。

            一個(gè)JMS場(chǎng)景通常需要三者參與:

          • 一個(gè)POJO的的Message Producer,負(fù)責(zé)使用Spring的JMS Template發(fā)送消息。
          • 一個(gè)Message Converter,負(fù)責(zé)把Java對(duì)象如訂單(Order)轉(zhuǎn)化為消息,使得Producer能夠直接發(fā)送POJO。
          • 一個(gè)MDP Message Consumer,負(fù)責(zé)接收并處理消息。

            SpringSide 2.0采用了ActiveMQ 4.1-incubator 與Spring 2.0 集成,對(duì)比SS1.0M3,有三個(gè)值得留意的地方,使得代碼中幾乎不見(jiàn)一絲JMS的侵入代碼:

          1. 采用Spring2.0的Schema式簡(jiǎn)化配置。
          2. 實(shí)現(xiàn)Message Converter轉(zhuǎn)化消息與對(duì)象,使得Producer能夠直接發(fā)送POJO而不是JMS Message。
          3. 使用了Spring2.0的DefaultMessageListenerContainer與MessageListenerAdapter,消息接收者不用實(shí)現(xiàn)MessageListener 接口。
          4. 同時(shí),Spring 2.0 的DefaultMessageListenerContainer 代替了SS1.0M3中的Jenck(JCA Container),充當(dāng)MDP Container的角色。

          2.引入ActiveMQ的XSD

            ActiveMQ4.1 響應(yīng)Spring 2.0號(hào)召,支持了引入XML Schema namespace的簡(jiǎn)單配置語(yǔ)法,簡(jiǎn)化了配置的語(yǔ)句。 

            在ApplicationContext.xml(Spring的配置文件)中引入ActiveMQ的XML Scheam 配置文件),如下:

          <beans
            xmlns="http://www.springframework.org/schema/beans"
            xmlns:amq="http://activemq.org/config/1.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd">

          由于ActiveMQ4.1 SnapShot的那個(gè)XSD有部分錯(cuò)誤,因此使用的是自行修改過(guò)的XSD。

          先在ClassPath根目錄放一個(gè)修改過(guò)的activemq-core-4.1-incubator-SNAPSHOT.xsd。

          在ClassPath 下面建立META-INF\spring.schemas 內(nèi)容如下。這個(gè)spring.schemas是spring自定義scheam的配置文件,請(qǐng)注意"http:\://"部分寫(xiě)法

          http\://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd=/activemq-core-4.1-incubator-SNAPSHOT.xsd

          3. 配置方案

          3.1 基礎(chǔ)零件 

          1. 配置ActiveMQ Broker  

             暫時(shí)采用在JVM中嵌入這種最簡(jiǎn)單的模式,  當(dāng)spring初始化時(shí)候,ActiveMQ embedded Broker 就會(huì)啟動(dòng)了。

          <!--  lets create an embedded ActiveMQ Broker -->
          <amq:broker useJmx="false" persistent="false">
            	<amq:transportConnectors>
              		<amq:transportConnector uri="tcp://localhost:0"/>
           	</amq:transportConnectors>
           </amq:broker>

          2. 配置(A)ConnectionFactory

            由于前面配置的Broker是JVM embedded 所以URL為:vm://localhost

          <!--  ActiveMQ connectionFactory to use  -->
           <amq:connectionFactory id="jmsConnectionFactory" brokerURL="vm://localhost"/>

          3 配置(B)Queue

          <!--  ActiveMQ destinations to use  -->
           <amq:queue name="destination" physicalName="org.apache.activemq.spring.Test.spring.embedded"/>

          4. 配置(C)Converter

             配置Conveter,使得Producer能夠直接發(fā)送Order對(duì)象,而不是JMS的Message對(duì)象。

          <!--  OrderMessage converter  -->
           <bean id="orderMessageConverter" class="org.springside.bookstore.components.activemq.OrderMessageConverter"/>  

          3.2  發(fā)送端 

          1 配置JmsTemplate

             Spring提供的Template,綁定了(A)ConnectionFactory與(C)Converter。

          <!--  Spring JmsTemplate config -->
           <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory">
             <!--  lets wrap in a pool to avoid creating a connection per send -->
             <bean class="org.springframework.jms.connection.SingleConnectionFactory">
              <property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
             </bean>
            </property>
            <!-- custom MessageConverter -->
            <property name="messageConverter" ref="orderMessageConverter"/>
           </bean>

          2.Producer

             消息發(fā)送者,使用JmsTemplate發(fā)送消息,綁定了JmsTemplate (含A、C)與(B)Queue。

          <!-- POJO which send Message uses  Spring JmsTemplate,綁定JMSTemplate 與Queue -->
           <bean id="orderMessageProducer" class="org.springside.bookstore.components.activemq.OrderMessageProducer">
            <property name="template" ref="jmsTemplate"/>
            <property name="destination" ref="destination"/>
           </bean>

          3.3 接收端

            1.接收處理者(MDP)

              使用Spring的MessageListenerAdapter,指定負(fù)責(zé)處理消息的POJO及其方法名,綁定(C)Converter。

            <!--  Message Driven POJO (MDP),綁定Converter -->
           <bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
            <constructor-arg>
             <bean class="org.springside.bookstore.components.activemq.OrderMessageConsumer">
              <property name="mailService" ref="mailService"/>
             </bean>
            </constructor-arg>
            <!--  may be other method -->
            <property name="defaultListenerMethod" value="sendEmail"/>
            <!-- custom MessageConverter define -->
            <property name="messageConverter" ref="orderMessageConverter"/>
           </bean> 

          2. listenerContainer

              負(fù)責(zé)調(diào)度MDP, 綁定(A) connectionFactory, (B)Queue和MDP。

          <!--  this is the attendant message listener container -->
           <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
            <property name="connectionFactory" ref="jmsConnectionFactory"/>
            <property name="destination" ref="destination"/>
            <property name="messageListener" ref="messageListener"/>
           </bean>

            互相綁定的關(guān)系有點(diǎn)暈,發(fā)送端和接收端都以不同形式綁定了(A) connectionFactory, (B)Queue和 (C)Converter。

          4. 下篇


          1. 說(shuō)明

             請(qǐng)先閱讀ActiveMQ4.1 +Spring2.0的POJO JMS方案(上)

             本篇將補(bǔ)充說(shuō)明了:

             1) 使用數(shù)據(jù)庫(kù)持久化消息,保證服務(wù)器重啟時(shí)消息不會(huì)丟失
             2) 使用Jencks作正宗的JCA Container。

          2.持久化消息

          2.1 給Broker加入Persistence 配置

          在配置文件applicationContext-activemq-embedded-persitence.xml中的<amq:broker>節(jié)點(diǎn)加入  

          <amq:persistenceAdapter>
          <amq:jdbcPersistenceAdapter id="jdbcAdapter" dataSource="#hsql-ds" createTablesOnStartup="true" useDatabaseLock="false"/>
          </amq:persistenceAdapter>

          請(qǐng)注意MSSQL(2000/2005)和HSQL由于不支持[SELECT  * ACTIVEMQ_LOCK FOR UPDATE ]語(yǔ)法,因此不能使用默認(rèn)的userDatabaseLock="true",只能設(shè)置成useDatabaseLock="false"

          2.2 配置多種數(shù)據(jù)源

          配置多種數(shù)據(jù)源,給jdbcPersistenceAdapter使用,SpringSide 中使用的內(nèi)嵌HSQL

           <!-- The HSQL Datasource that will be used by the Broker -->
          <bean id="hsql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
          <property name="url" value="jdbc:hsqldb:res:hsql/activemq"/>
          <property name="username" value="sa"/>
          <property name="password" value=""/>
          <property name="poolPreparedStatements" value="true"/>
          </bean>

          2. 3 說(shuō)明

             筆者僅僅使用了jdbcPersistenceAdapter,其實(shí)在ActiveMQ的XSD已經(jīng)描述了多種PersistenceAdapter,可以參考對(duì)應(yīng)的XSD文件.

            另外對(duì)于數(shù)據(jù)庫(kù)的差異主要表現(xiàn)在設(shè)置了userDatabaseLock="true"之后,ActiveMQ使用的[SELECT * ACTIVEMQ_LOCK FOR UPDATE] 上面,會(huì)導(dǎo)致一些數(shù)據(jù)庫(kù)出錯(cuò)(測(cè)試中MSSQL2000/2005,HSQL都會(huì)導(dǎo)致出錯(cuò))。另外HSQL的腳本請(qǐng)參見(jiàn)activemq.script。

          3. Jenck(JCA Container)  

             Spring 2.0本身使用DefaultMessageListenerContainer 可以充當(dāng)MDP中的Container角色,但是鑒于Jencks是JCA標(biāo)準(zhǔn)的,它不僅僅能夠提供jms的jca整合,包括其他資源比如jdbc都可以做到j(luò)ca管理

          所以,同時(shí)完成了這個(gè)ActiveMQ+Spring+Jencks 配置演示,更多的針對(duì)生產(chǎn)系統(tǒng)的JCA特性展示,會(huì)在稍后的開(kāi)發(fā)計(jì)劃討論中確定。

               此文檔適用于說(shuō)明使用 Jecncks 和 使用Spring 2.0(DefaultMessageListenerContainer)  充當(dāng)MDP Container時(shí)的區(qū)別,同時(shí)演示Jecnks 的Spring 2.0 新配置實(shí)例。

          3.1 引入ActiveMQ ResourceAdapter 和Jencks 的XSD

            在ApplicationContext.xml(Spring的配置文件)中引入ActiveMQ ResourceAdapter 和Jencks 的XML Scheam 配置文件),如下:

             ActiveMQ4.1 響應(yīng)Spring 2.0號(hào)召,支持了引入XML Schema namespace的簡(jiǎn)單配置語(yǔ)法,簡(jiǎn)化了配置的語(yǔ)句。 

            在ApplicationContext.xml(Spring的配置文件)中引入ActiveMQ的XML Scheam 配置文件),如下:

          <beans
          xmlns="http://www.springframework.org/schema/beans"   xmlns:amq="http://activemq.org/config/1.0"   xmlns:ampra="http://activemq.org/ra/1.0"   xmlns:jencks="http://jencks.org/1.3"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd
            http://activemq.org/ra/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-ra-4.1-incubator-SNAPSHOT.xsd
            http://jencks.org/1.3 http://repository.codehaus.org/org/jencks/jencks/1.3/jencks-1.3.xsd">

          由于ActiveMQ RA和Jencks 那個(gè)XSD 仍然有部分錯(cuò)誤,因此使用的是自行修改過(guò)的XSD。(是xs:any元素引起的錯(cuò)誤)

          先在ClassPath根目錄放一個(gè)修改過(guò)的activemq-ra-4.1-incubator-SNAPSHOT.xsd和jencks-1.3.xsd。

          同樣修改 ClassPath 下面META-INF\spring.schemas 增加內(nèi)容如下。這個(gè)spring.schemas是spring自定義scheam的配置文件,請(qǐng)注意"http:\://"部分寫(xiě)法

          http\://people.apache.org/repository/org.apache.activemq/xsds/activemq-ra-4.1-incubator-SNAPSHOT.xsd=/activemq-ra-4.1-incubator-SNAPSHOT.xsd
          http\://repository.codehaus.org/org/jencks/jencks/1.3/jencks-1.3.xsd=/jencks-1.3.xsd

          3.2  配置方案

          3.2.1 基礎(chǔ)零件 

          1. 配置ActiveMQ Broker  參見(jiàn) ActiveMQ+Spring

          2. 配置ActiveMQ Resource Adapter

          <amqra:managedConnectionFactory id="jmsManagedConnectionFactory" resourceAdapter="#resourceAdapter"/><amqra:resourceAdapter id="resourceAdapter" serverUrl="vm://localhost" />

          3. 配置Jencks 基礎(chǔ)配置

             具體的配置可以參見(jiàn)Jencks的XSD

          <!-- jencks PoolFactory config-->
          <jencks:singlePoolFactory id="poolingSupport" maxSize="16" minSize="5" blockingTimeoutMilliseconds="60" idleTimeoutMinutes="60" matchOne="true" matchAll="true" selectOneAssumeMatch="true" /> <!-- jencks XATransactionFactory -->
          <jencks:xATransactionFactory id="transactionSupport" useTransactionCaching="true" useThreadCaching="true" />  
          <!-- jencks ConnectionManagerFactory -->
          <jencks:connectionManagerFactory id="connectionManager" containerManagedSecurity="false"  poolingSupport="#poolingSupport" transactionSupport="#transactionSupport" /> <!-- jencks TransactionContextManagerFactory -->
          <jencks:transactionContextManagerFactory id="transactionContextManagerFactory"/>
            

          4. 配置給JmsTemplate使用的connectionFactory (主要是生成者/發(fā)送者 使用)

             這里注意下,在配置jmsTemplate的使用的targetConnectionFactory就是使用jencks配置的connectionManager

          <!-- spring config jms with jca-->
           <bean id="jmsManagerConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
            <property name="managedConnectionFactory">
             <ref local="jmsManagedConnectionFactory" />
            </property>
            <property name="connectionManager">
             <ref local="connectionManager" />
            </property>
           </bean>
           
           <!--  Spring JmsTemplate config -->
           <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory">
             <!--  lets wrap in a pool to avoid creating a connection per send -->
             <bean class="org.springframework.jms.connection.SingleConnectionFactory">
                  <property name="targetConnectionFactory" ref="jmsManagerConnectionFactory" />
             </bean>
            </property>
            <!-- custom MessageConverter -->
            <property name="messageConverter" ref="orderMessageConverter" />
           </bean>  

          5. 配置Spring 2.0的MessageListenerAdapter,保證不需要用戶(hù)實(shí)現(xiàn)MessageListener

             見(jiàn)ActiveMQ+Spring

           6.配置Jecnks 充當(dāng)MDP的Container

            就是把上面的MessageListenerAdapter配置到Jencks里面,完成整個(gè)MDP的配置

           <!-- Jencks Container-->
           <jencks:jcaContainer>  	<jencks:bootstrapContext>
             		<jencks:bootstrapContextFactory threadPoolSize="25" />
            	</jencks:bootstrapContext>
            		<jencks:connectors>
             	   <!-- use jencks container (use spring MessageListenerAdapter)-->
             		<jencks:connector ref="messageListener">
              			<jencks:activationSpec>
               				<amqra:activationSpec destination="org.apache.activemq.spring.Test.spring.embedded" destinationType="javax.jms.Queue" />
              			</jencks:activationSpec>
             		</jencks:connector>  	</jencks:connectors> 		 <jencks:resourceAdapter>
             		<amqra:resourceAdapter serverUrl="vm://localhost" />
            	</jencks:resourceAdapter>
           </jencks:jcaContainer>

          posted @ 2008-04-12 01:37 hk2000c 閱讀(755) | 評(píng)論 (0)編輯 收藏

          請(qǐng)參考一下馬琳、王皓的主管教練吳敬平的文章

          直板反膠正手拉球的基本原理和訓(xùn)練方法

          乒乓球基本上是一項(xiàng)圓周運(yùn)動(dòng),正手和反手拉球都是以運(yùn)動(dòng)員的身體重心為軸心、以身體到身體重心的連線為半徑進(jìn)行圓周運(yùn)動(dòng)。因此,不管是正手還是反手擊球都必須符合這個(gè)原理,從這個(gè)意義上講,正手拉球動(dòng)作的基本原理就是一種力的傳遞。
          正手拉球的基本要點(diǎn)
          基本站位:兩腿張開(kāi)與肩的寬度為差不多相同,身體稍微前傾,重心在前腳掌上,拉球時(shí),身體向右轉(zhuǎn)(以右手為例),重心放在右腳上,在轉(zhuǎn)腰的過(guò)程中,用腰控制大臂,右肩稍底,小臂自然下垂,用手腕控制板型,板型前傾(拇指用力壓住球板,食指稍微放松,中指頂住球板),板型前傾的角度因來(lái)球的旋轉(zhuǎn)不同而調(diào)整。
          擊球原理:擊球的時(shí)候,以右手為例,首先是腿上發(fā)力,向左蹬腿,身體重心從右腳向左腳轉(zhuǎn)換,交換重心,身體前迎,身體前迎的方向要和擊球的方向一致。然后是腰上發(fā)力,用腰帶動(dòng)大臂轉(zhuǎn)動(dòng),把力傳遞到前臂,在擊球一瞬間,收縮前臂用力擊球。從力學(xué)的原理講,正手拉球前,小臂和大臂之間的角度越小越好,這是加大半徑,半徑越大,初速度就越大,在擊球瞬間突然收縮前臂,使半徑變小而獲得加速度,使速度加快,力量加大。擊球時(shí),小臂和大臂之間角度的變化要根據(jù)來(lái)球和擊球的需要進(jìn)行變化。很多運(yùn)動(dòng)員在進(jìn)行正手拉球時(shí)往往只注意了收前臂而忽略了轉(zhuǎn)腰,用腰來(lái)控制手臂的發(fā)力,或者是注意了用腰的發(fā)力來(lái)帶動(dòng)手臂而忽略了收前臂,前臂和大臂之間的角度幾乎沒(méi)有變化或變化很小。總結(jié)起來(lái)正手拉球應(yīng)注意四點(diǎn):1、必須注意重心的交換,重心迎前的方向要和擊球的方向一致。2、一定要用腰控制大臂,是腰上發(fā)力,而不是用手臂發(fā)力,注意拉球時(shí)腿、腰、大臂、前臂、手腕發(fā)力的協(xié)調(diào)。3、擊球瞬間必須快速收縮前臂、手腕發(fā)力,前臂收縮的速度越快,發(fā)出的力量就越大。4、擊球點(diǎn)必須保持在身體的右前方,擊球點(diǎn)離身體越近,越容易控制球。有一點(diǎn)值得注意的是不管是什么樣的拉球動(dòng)作,必須和你自身具備的身體條件相符合,只要不影響動(dòng)作的發(fā)力就可以,沒(méi)有什么固定的動(dòng)作模式。另外就是在擊球前,球板和球之間要有一定的距離,盡量主動(dòng)去擊球,而不要讓球來(lái)撞你的球拍,或者是球與球拍之間的距離太小,容易被來(lái)球頂住,影響你的發(fā)力。

          正手拉球的方法與技巧
          正手拉球是一門(mén)很復(fù)雜的技術(shù),有近臺(tái)拉球、中近臺(tái)拉球、遠(yuǎn)臺(tái)拉球,有拉上旋球、下旋球,有近臺(tái)快帶、反拉弧圈球,拉半出臺(tái)球等等。不管拉球有多么復(fù)雜,但有一點(diǎn)是最重要的基礎(chǔ),就是步法。步法的好壞,直接關(guān)系到正手拉球的命中率、力量的大小和拉球時(shí)的調(diào)節(jié)能力。要想練好正手拉球,就必須先練好步法。而在這一點(diǎn)上,是專(zhuān)業(yè)運(yùn)動(dòng)員和業(yè)余運(yùn)動(dòng)員最大的區(qū)別所在,業(yè)余運(yùn)動(dòng)員不可能像專(zhuān)業(yè)運(yùn)動(dòng)員那樣進(jìn)行大量的高強(qiáng)度的步法訓(xùn)練。但有一點(diǎn)是相同的,那就是擊球的技巧。只要能夠做到因勢(shì)利導(dǎo),充分發(fā)揮現(xiàn)有的條件,也會(huì)收到一定的效果。下面,我給大家介紹一些比較實(shí)用的訓(xùn)練方法和技巧:
          1、拉好定點(diǎn)下旋球:拉沖下旋球是直板反膠最基礎(chǔ)的基本功,在拉下旋球時(shí)除了注意前面提到的基本動(dòng)作要領(lǐng)以外,要特別注意手腕的用力方法。在擊球的瞬間是用手腕去摩擦球,擊球點(diǎn)在來(lái)球的中上部,在用手腕摩擦球時(shí)還要根據(jù)來(lái)球旋轉(zhuǎn)的強(qiáng)弱再加上一定的撞擊。就是人們常說(shuō)的又摩又打。拉沖下旋球旋轉(zhuǎn)弱的來(lái)球要連摩擦帶撞擊,撞擊可稍大于摩擦。拉沖下旋球旋轉(zhuǎn)強(qiáng)的來(lái)球必須用力摩擦擊球,用自己拉球的力量抵消來(lái)球的旋轉(zhuǎn)。在擊球的瞬間要特別注意擊球時(shí)一定要把球往前送,不能靠力量去硬碰球。這就是我們常說(shuō)的“吃球”,盡量讓球在球板上停留的時(shí)間長(zhǎng)一些。經(jīng)常這樣訓(xùn)練拉球,你對(duì)球的感覺(jué)就會(huì)越來(lái)越好,拉球就會(huì)越來(lái)越有數(shù),慢慢達(dá)到運(yùn)用自如。訓(xùn)練的方法,在沒(méi)有多球條件的情況下可采用拉球一方發(fā)下旋球到對(duì)方的反手位讓對(duì)方搓長(zhǎng)球到側(cè)身位,然后發(fā)力拉沖這個(gè)球。拉球時(shí)一定要注意用全力拉沖,不要考慮下一板球?qū)Ψ绞欠衲軌蚍肋^(guò)來(lái)。要的就是讓你防不過(guò)來(lái)。經(jīng)常這樣訓(xùn)練,你的拉球力量一定會(huì)提高。在有多球的條件下,可讓對(duì)方發(fā)下旋球到你的側(cè)身位,定點(diǎn)發(fā)力拉沖這種球。拉球時(shí)要掌握好擊球時(shí)間,在對(duì)方來(lái)球跳到最高點(diǎn)或下降前期擊球最好。擊球時(shí)間一定要相對(duì)固定,這樣容易掌握拉球的命中率,好調(diào)節(jié)。出界多就向前送一點(diǎn),下網(wǎng)多就多摩擦一點(diǎn)。在定點(diǎn)拉沖下旋球比較有數(shù)的情況下,再把來(lái)球的落點(diǎn)擴(kuò)大到全臺(tái)的定點(diǎn)拉沖,這樣不斷加大拉球的難度,拉球的水平就會(huì)不斷提高。
          2、拉好定點(diǎn)上旋球:拉上旋球和下旋球不同的是,拉上旋球擊球點(diǎn)在來(lái)球的上部,摩擦球要大于撞擊球,擊球的瞬間一定要往前送。訓(xùn)練的方法基本和搶拉下旋球一樣,只是來(lái)球的旋轉(zhuǎn)不一樣,是上旋球。在推擋后側(cè)身發(fā)力拉沖這板球,或?qū)Ψ阶兡阏治缓蟀l(fā)力拉沖,反復(fù)練習(xí)。有多球訓(xùn)練的條件,可以由對(duì)方直接發(fā)上旋球到你的正手位和側(cè)身位搶沖,落點(diǎn)可以從定點(diǎn)到不定點(diǎn),逐步提高擊球的難度。
          3、練好反拉弧圈球:反拉弧圈球是一種高級(jí)技術(shù),尤其是業(yè)余運(yùn)動(dòng)員掌握了這項(xiàng)技術(shù)就像如魚(yú)得水,你就掌握了比賽的主動(dòng)權(quán)。因?yàn)橐话愕臉I(yè)余運(yùn)動(dòng)員在拉弧圈球時(shí)拉高吊弧圈球的時(shí)候多,你掌握了反拉弧圈球的技術(shù),你就站在了比對(duì)方高一擋的層次上。反拉弧圈球的要領(lǐng),首先要自己發(fā)力,盡量少借對(duì)方的旋轉(zhuǎn),用自己拉球的力量去抵消對(duì)方來(lái)球的旋轉(zhuǎn)。其次是在反拉時(shí)摩擦球一定要薄,摩擦球的上部甚至頂部,既要借對(duì)方來(lái)球的旋轉(zhuǎn)的力,還要自己發(fā)力摩擦球。越是自己發(fā)力反拉,命中率越高。越是怕對(duì)方的旋轉(zhuǎn)去碰球,越是容易吃對(duì)方的旋轉(zhuǎn)。訓(xùn)練的方法,對(duì)方發(fā)下旋球到你的反手位,你搓球到對(duì)方側(cè)身位,對(duì)方拉高吊弧圈球到你反手位,你側(cè)身反拉,這樣反復(fù)練習(xí),等基本掌握了反拉弧圈球的規(guī)律以后,再把反拉擴(kuò)大到全臺(tái)和不定點(diǎn)反拉。
          4、近臺(tái)正手快帶弧圈球:這項(xiàng)技術(shù)是防守中很先進(jìn)的技術(shù),也是很難掌握的技術(shù),是90年代后期才逐漸被采用的技術(shù)。在這之前人們?cè)谡治坏姆朗囟际瞧綋酰鑼?duì)方來(lái)球的旋轉(zhuǎn)把球擋過(guò)去,因而在比賽關(guān)鍵的時(shí)刻就很容易因緊張而造成失誤,即使不失誤,防過(guò)去的球也沒(méi)有威脅,很容易被對(duì)方連續(xù)進(jìn)攻。到90年代后期,中國(guó)的運(yùn)動(dòng)員把反拉的技術(shù)運(yùn)用在近臺(tái)的防守上,特別是直板反膠打法的運(yùn)動(dòng)員運(yùn)用更多,加快了攻防轉(zhuǎn)換的節(jié)奏,收到了很好的效果,馬林在這項(xiàng)技術(shù)的運(yùn)用上是非常突出的。這項(xiàng)技術(shù)要求運(yùn)動(dòng)員的對(duì)來(lái)球的判斷要非常快、準(zhǔn)確,手上對(duì)球的感覺(jué)要求很高,因?yàn)橛泻芏嗲蚴窃谑ド眢w重心或不到位的情況下,完全靠運(yùn)動(dòng)員手上的功夫去完成技術(shù)動(dòng)作。我想雖然目前在業(yè)余運(yùn)動(dòng)員中能真正掌握這項(xiàng)技術(shù)的不多,但已經(jīng)具備了一定水平的運(yùn)動(dòng)員可以去嘗試一下,也許你會(huì)有意外的收獲。
          這項(xiàng)技術(shù)的技巧主要在于掌握好擊球時(shí)間和手腕的用力,擊球時(shí)間盡量在球的起跳前期(上升期),當(dāng)步法實(shí)在到不了位的情況下,還可以在球剛一跳起時(shí)就擊球。擊球時(shí)靠腰和手腕發(fā)力,接觸球的頂部。接觸球時(shí)既要借對(duì)方來(lái)球旋轉(zhuǎn)的力,同時(shí)自己一定要發(fā)力去摩擦球,盡量摩擦薄一點(diǎn),摩擦厚就容易下網(wǎng),在摩擦球的瞬間一定要把球往前頂。訓(xùn)練方法可采用搓下旋球到對(duì)方正手位讓對(duì)方拉弧圈球到自己的正手位,然后正手近臺(tái)快帶。這樣反復(fù)練習(xí)就會(huì)逐漸掌握擊球的基本方法,在快帶對(duì)方從下旋球拉起來(lái)的弧圈球比較熟練的情況下,再進(jìn)行推直線讓對(duì)方拉弧圈球到自己的正手位快帶上旋弧圈球的訓(xùn)練。這樣,你就會(huì)慢慢掌握在防守中正手近臺(tái)快帶弧圈球的技術(shù)。這項(xiàng)技術(shù)的關(guān)鍵點(diǎn)是在擊球時(shí)一定摩擦球要薄,而且自己一定要主動(dòng)發(fā)力去帶球。

          正手拉球的注意事項(xiàng)
          業(yè)余選手在練習(xí)正手拉球時(shí),要注意掌握以下幾點(diǎn):
          1、收前臂:在正手拉球時(shí)一定要注意收前臂,大臂和小臂之間的角度一定不能固定,要根據(jù)來(lái)球來(lái)決定擺臂的大小。但要注意一點(diǎn),收前臂一定要用腰來(lái)控制。
          2、轉(zhuǎn)腰:由于乒乓球是圓周運(yùn)動(dòng),擊球時(shí)用腰來(lái)控制手是非常重要的環(huán)節(jié),擊球時(shí)球拍的后引不是用手往后拉手,而是用轉(zhuǎn)腰來(lái)完成,用腰固定大臂,轉(zhuǎn)腰的速度要遠(yuǎn)遠(yuǎn)快于拉手。就是說(shuō),在擊球前的擺臂是先轉(zhuǎn)腰而不是先拉手。而我們好多球迷們?cè)诖蚯驎r(shí)都是先拉手,不知道轉(zhuǎn)腰,因而在擊球時(shí)經(jīng)常出現(xiàn)身體不協(xié)調(diào)導(dǎo)致發(fā)力不集中或發(fā)不出力。
          3、擊球點(diǎn):擊球點(diǎn)的最佳位置是在身體的右前方(以右手為例),要保持最佳的擊球位置就必須學(xué)好步法,保持好身體的重心,重心的高低要根據(jù)來(lái)球來(lái)決定。馬林經(jīng)常使用的側(cè)身倒地爆沖是不得已而為之,對(duì)方搓過(guò)來(lái)的球又低又長(zhǎng),拉完以后不可能再還原,只有搏殺。馬林在拉這種球的時(shí)候重心低,但是擊球點(diǎn)是球的最高點(diǎn)或下降前期。正手位大角度的球擊球點(diǎn)要根據(jù)自己步法移動(dòng)的情況來(lái)決定擊球點(diǎn)的高低。一般情況下是在球的下降中期和后期擊球。
          4、手腕的運(yùn)用:在拉球時(shí),手腕要相對(duì)固定,不能晃動(dòng)太大,擊球瞬間用中指頂住球板發(fā)力摩擦球。另外手腕還具有擊球瞬間的調(diào)節(jié)功能,比如在拉球時(shí)突然感到球的旋轉(zhuǎn)比自己預(yù)想的要轉(zhuǎn)時(shí)就靠手腕來(lái)調(diào)節(jié)擊球的力量大小和摩擦球的部位。在不到位和頂住自己的情況下,就要靠腰和手腕來(lái)調(diào)節(jié)擊球點(diǎn)。特別是在比賽中,很多球都不是很規(guī)則,來(lái)球的落點(diǎn)也是你最難受的地方,這時(shí)候就要靠手腕來(lái)調(diào)節(jié),手腕的調(diào)節(jié)主要靠大拇指和中指用力來(lái)完成。其次拉球時(shí)板型的控制也要靠手腕來(lái)完成,有很多的直板運(yùn)動(dòng)員正手拉球時(shí)吊腕很厲害,這影響發(fā)力,一般情況下,手腕和前臂幾乎在一條直線上,球板把與手腕之間的角度在45度左右。
          5、吃球:我們看一個(gè)運(yùn)動(dòng)員拉球的好壞,主要是看他拉球時(shí)是否吃球。吃球就是球在球板上的停留時(shí)間比較長(zhǎng),而不是球一碰球板就出去了。要做到拉球時(shí)吃球,就必須每一板球都主動(dòng)發(fā)力去摩擦球,在平時(shí)的訓(xùn)練中盡量少打借力球。拉球吃球的好壞,在平時(shí)訓(xùn)練中不是很明顯,但在比賽中就有很大的區(qū)別。很多球都是在你不到位的情況下要完成拉球的動(dòng)作,就全靠你用手腕主動(dòng)發(fā)力去摩擦球來(lái)調(diào)節(jié),你習(xí)慣了主動(dòng)發(fā)力拉球,就能在比賽中控制拉球時(shí)力量和擊球部位的調(diào)節(jié),拉過(guò)去很多高難度的球。
          6、搶沖上旋球和下旋球的區(qū)別:動(dòng)作上沒(méi)有多大的區(qū)別,區(qū)別在于搶沖下旋球時(shí)擊球點(diǎn)在球的中上部,發(fā)力的時(shí)候根據(jù)來(lái)球的旋轉(zhuǎn)可帶點(diǎn)撞擊;搶沖上旋球時(shí)擊球點(diǎn)在球的頂部,主動(dòng)發(fā)力摩擦球,擊球時(shí)身體重心也隨之向前。特別是在反拉弧圈球時(shí),摩擦薄反而容易過(guò)去,摩擦厚或帶點(diǎn)撞擊就容易失誤。
          7、微調(diào):很多球迷朋友提出這個(gè)問(wèn)題,我認(rèn)為要在比賽中做到這一點(diǎn)是比較難的。這首先取決于你個(gè)人本身的球感,就是你手上對(duì)球的感覺(jué)。其次是在訓(xùn)練中不斷地培養(yǎng)你對(duì)球的旋轉(zhuǎn)的理解,要清楚地知道你打過(guò)去的球是什么樣的旋轉(zhuǎn),對(duì)方回過(guò)來(lái)的球又是什么樣的旋轉(zhuǎn)。只有這樣,你才會(huì)根據(jù)來(lái)球的不同,在很困難正常擊球的情況下,在來(lái)球很不規(guī)則的情況下,在球落在邊邊角角很難回?fù)舻那闆r下,通過(guò)手上的調(diào)節(jié)把球回?fù)暨^(guò)去。因此,對(duì)于業(yè)余球迷朋友們來(lái)講,最主要的是去琢磨球的旋轉(zhuǎn)變化,把這個(gè)規(guī)律基本掌握住了,你就具備了微調(diào)的能力
          正手弧圈球技術(shù)是乒乓球技術(shù)中最基本也是最重要的技術(shù)之一。拉好弧圈球的三個(gè)要素就是腿、腰、手;三者要協(xié)調(diào)一致,才能發(fā)揮弧圈球的最大威力。


          從弧圈球的風(fēng)格上來(lái)講,目前主要分為歐洲派和亞洲派。歐洲選手拉弧圈球的時(shí)候,撞擊的成分比較多,因此球在飛行的過(guò)程中速度快,力量大,弧線低;亞洲選手拉弧圈球的時(shí)候,摩擦的成分比較多,因此球在彈起后的過(guò)程中速度快,旋轉(zhuǎn)強(qiáng),弧線低。隨著弧圈球技術(shù)的發(fā)展,目前各國(guó)選手都在相互學(xué)習(xí),相互借鑒,因此并沒(méi)有十分明顯的風(fēng)格區(qū)別,而是根據(jù)不同的球運(yùn)用不同的技術(shù)。

          弧圈球的基本技術(shù)動(dòng)作并不難,但是要想拉好弧圈球必須要勤學(xué)苦練,才能是自己的技術(shù)有大幅度的提高。如何掌握基本的弧圈球技術(shù)呢?(以右手握拍選手為例)

          一、技術(shù)動(dòng)作分解

          1.準(zhǔn)備動(dòng)作:

          拉球之前,站位一定要合理。一般來(lái)說(shuō),站位距球臺(tái)邊緣1.5米左右。左腳前,右腳后,兩腳間距略比肩寬,右腳尖于左腳腳窩的位置平齊,以?xún)赡_前腳掌內(nèi)側(cè)著地。兩腿彎曲,含胸,重心放低,身體與球臺(tái)邊緣的夾角大概為45度左右。

          2.拉球:

          拉上旋球時(shí),右肩略微下沉,同時(shí)橫向轉(zhuǎn)腰,右臂自然放松,靠橫向轉(zhuǎn)腰動(dòng)作完成引拍的過(guò)程。此時(shí),以右腳為軸,重心放到右腿上。然后,右腿蹬地,腰部橫向回轉(zhuǎn),并帶動(dòng)右臂,注意此時(shí)右臂仍為放松狀態(tài)。待腰轉(zhuǎn)到基本與球臺(tái)邊緣平行的時(shí)候開(kāi)始收縮前臂,擊球。重心由右腿轉(zhuǎn)移到兩腿上,兩肩持平。擊球時(shí),要找好擊球時(shí)間。擊球時(shí)間分為上升期和下降期,上升期是指來(lái)球即將達(dá)到最高點(diǎn)的時(shí)候,下降期是指來(lái)球從最高點(diǎn)剛剛下落的時(shí)候。一般來(lái)說(shuō),來(lái)球位于右腹部前方一尺多的距離時(shí)擊球感覺(jué)最好,可以發(fā)出力。擊球時(shí),要注意摩擦球,主要向前發(fā)力。擊球后要注意大臂、小臂立刻放松,還原。
          此主題相關(guān)圖片如下:


          關(guān)于擊球部位,對(duì)于以拉打?yàn)橹骱湍Σ翞橹魇怯袇^(qū)別的。 以拉打?yàn)橹鞯倪x手,擊球的部位一般為B點(diǎn)或B、C點(diǎn)之間。以摩擦為主的選手,擊球部位一般為C點(diǎn)。
          拉下旋球的動(dòng)作要領(lǐng)與拉上旋球基本一致。只是拉下旋球時(shí),右肩沉的更低一些,擊球的部位一般為B點(diǎn),且用力的方向向上多一些。

          3.步法

          拉球時(shí),要根據(jù)來(lái)球的位置,時(shí)刻跑動(dòng)來(lái)調(diào)節(jié)擊球的最佳位置。跑動(dòng)時(shí)要保證重心盡量平穩(wěn),身體不要亂晃。

          二、高吊弧圈與前沖弧圈

          高吊弧圈一般是針對(duì)拉下旋球而言的。高吊弧圈以旋轉(zhuǎn)見(jiàn)長(zhǎng),但是弧線略高,速度較慢。高吊弧圈的擊球部位一般為B點(diǎn),甚至是A、B點(diǎn)之間,這要根據(jù)來(lái)球的旋轉(zhuǎn)而定。拉高吊弧圈,右肩下沉的較低,用力方向向上的比較多,先要制造一個(gè)高過(guò)球網(wǎng)的弧線,然后用力方向向前,再制造一個(gè)向前的弧線。如果一味的向上硬拉,則球很容易出界。

          前沖弧圈速度快,力量大,但旋轉(zhuǎn)稍遜。拉前沖弧圈,擊球部位一般為C點(diǎn)或B、C點(diǎn)之間。右肩略微下沉,用力方向向前比較多。若來(lái)球的下旋旋轉(zhuǎn)很強(qiáng),則必須增加轉(zhuǎn)腰的幅度和前臂收縮的速度,以增大對(duì)球的摩擦力。

          三、臺(tái)內(nèi)弧圈球技術(shù)

          臺(tái)內(nèi)弧圈球的技術(shù)難度比較大。首先要判斷來(lái)球的位置和高度,根據(jù)來(lái)球的高度來(lái)決定引拍的高度。拉臺(tái)內(nèi)弧圈球,一般引拍的高度較高,往往與臺(tái)面高度持平,甚至高于臺(tái)面。擊球部位一般為D點(diǎn)。由于摩擦球的部位很薄,因?yàn)閷?duì)于下旋非常強(qiáng)的臺(tái)內(nèi)球,處理起來(lái)難度很大。而對(duì)于不太轉(zhuǎn)的下旋球來(lái)說(shuō),臺(tái)內(nèi)弧圈球給對(duì)方造成的威脅還是很大的。拉臺(tái)內(nèi)弧圈球,要注意用力方向向上多一些,繼而向前,要把弧線拉短。

          四、套膠與弧圈球

          進(jìn)口套膠與國(guó)產(chǎn)套膠的性能不同,對(duì)于拉弧圈球的風(fēng)格有一定的影響。
          歐洲人拉球多為拉打,因?yàn)闅W洲的套膠膠皮黏性差,海綿偏軟,但彈性好。使用進(jìn)口套膠,球在接觸到拍子之后,海綿被擠壓的程度較深,海綿被壓縮的行程長(zhǎng),這樣就削減了來(lái)球的大部分旋轉(zhuǎn)和力量,因此采用拉打的手法可以很好的控制來(lái)球,加之歐洲人身高馬大,爆發(fā)力非常好。這樣的拉球威力不小。

          亞洲人拉球多摩擦,因?yàn)閲?guó)產(chǎn)的套膠,如狂飆系列套膠,膠皮黏性強(qiáng),海綿彈性非常實(shí)在,非常大。在球接觸拍子的時(shí)候,膠皮給了來(lái)球很大的阻力,而海綿被壓縮的程度也不大,這樣就造成的脫板速度很快。因此只有多摩擦,以旋轉(zhuǎn)克旋轉(zhuǎn)才能拉出高質(zhì)量的弧圈球。所以使用國(guó)產(chǎn)套膠對(duì)拉球的技術(shù)要求較高。

          隨著乒乓器材的發(fā)展,國(guó)內(nèi)已經(jīng)生產(chǎn)出很多新產(chǎn)品,兼具了國(guó)產(chǎn)與進(jìn)口的很多優(yōu)點(diǎn),對(duì)于眾多的乒乓球愛(ài)好者來(lái)說(shuō),又多了很多的選擇。

          五、拉球的常見(jiàn)問(wèn)題
          1. 重心后坐。
          重心后坐,自然使腿部力量不能發(fā)揮出來(lái),使手臂的走向多為向上,削減了拉球的速度、力量和旋轉(zhuǎn)。
          2. 手臂僵硬。
          引手的過(guò)程中,肌肉僵硬,大大降低了控制球的能力,并鎖住了力量。擊球后肌肉僵硬,使力量不能全部發(fā)揮出來(lái),并降低了還原速度。
          3. 轉(zhuǎn)腰不夠。
          只靠手臂拉球,速度、力量、旋轉(zhuǎn)都有很大的損失。
          4. 抬肘、抬肩。
          使腿、腰、手不能協(xié)調(diào)一致,當(dāng)力量從腿、腰傳到手的時(shí)候,能量中斷。
          5.步法遲鈍。
          等球,使擊球點(diǎn)太低,使全身的力量用不到球上。
          posted @ 2008-03-08 01:23 hk2000c 閱讀(725) | 評(píng)論 (0)編輯 收藏


          拉弧圈最重要的環(huán)節(jié)是什么?是吃球。

          就是盡量延長(zhǎng)球和膠皮接觸的時(shí)間,主動(dòng)發(fā)力控球,把揮拍的能量充分作用到球體上。吃球就是球在球板上的停留時(shí)間比較長(zhǎng),而不是球一碰球板就出去了。要做到拉球時(shí)吃球,就必須每一板球都主動(dòng)發(fā)力去摩擦球,在平時(shí)的訓(xùn)練中盡量少打借力球。

          延長(zhǎng)控球時(shí)間靠是什么?反膠、軟板、灌膠、先打后摩,還有最重要的一點(diǎn)是在加速揮拍過(guò)程中擊球。加速擊球就好比在阻力較小的平面上推箱子,只有不斷加速去推,才能一直不離手,力量才能充分傳遞到箱子上。也就是說(shuō),拉弧圈最好是不斷加速追著球摩擦。

          如果拉上旋來(lái)球,就是逆旋轉(zhuǎn)擊球,球和膠皮接觸的瞬間,球和膠皮的相對(duì)速度大,來(lái)球減轉(zhuǎn)的過(guò)程就是個(gè)緩沖過(guò)程,球不會(huì)很快脫板,一般不會(huì)有吃不住球的感覺(jué)。

          如果拉下旋來(lái)球,則是順旋轉(zhuǎn)擊球,如果揮拍向上的速度低于旋轉(zhuǎn), 便無(wú)法吃得住球。就好比玩陀螺,抓住轉(zhuǎn)動(dòng)的陀螺容易,因?yàn)槭悄嫘D(zhuǎn),而給陀螺加轉(zhuǎn)就很困難,要用比陀螺更快速度的鞭子去抽。這一點(diǎn)對(duì)著削球手感覺(jué)最為明顯,力量還沒(méi)作用到球上,球就脫板了,常會(huì)有吃不住球的情況發(fā)生。如果仔細(xì)觀察錄像,國(guó)手們拉削球時(shí)揮拍摩擦都極快,揮拍之所以快的就是靠發(fā)力抵消來(lái)球的旋轉(zhuǎn)。對(duì)下旋來(lái)球, 揮拍速度是不能低于旋轉(zhuǎn)的。

          拉下旋球?yàn)楸WC能吃住球需掌握三個(gè)要點(diǎn):

          一是增大球和球板的正壓力,就是“又摩又打”,增大正壓力便于摩擦。

          二是加快向上向前的揮拍速度,包括手腕也要加上摩擦球的動(dòng)作。

          三是掌握擊球時(shí)間。一般是在下降期拉,一方面下旋球在空中飛行時(shí)會(huì)逐漸減轉(zhuǎn),另一方面,球在下落時(shí)由于下落速度和球的旋轉(zhuǎn)方向相反,兩個(gè)速度相抵,揮拍相對(duì)速度就體現(xiàn)的更快一些。

          第一板從下旋拉起的弧圈很難防守,也是因?yàn)榫哂衅?#8220;順旋”的加成效果。一旦練成,對(duì)對(duì)手威懾極大。





          前言:都說(shuō)下旋球下降期好拉,為甚么?什么出轉(zhuǎn)沒(méi)出轉(zhuǎn),都是憑感覺(jué)。請(qǐng)看物理學(xué)的精確分析。我們對(duì)事物不僅要知其然,也要知其所以然。

          如圖:球?yàn)橄滦O(shè)球拍垂直向上摩擦,與球在a點(diǎn)接觸。假設(shè)球旋轉(zhuǎn)每秒30轉(zhuǎn),直徑40MM,則a點(diǎn)線速度為:

          V2=2πr*30 = 3.768m /s(即如果球原地向上轉(zhuǎn),a點(diǎn)的對(duì)地速度)

          1、拉上升期,a點(diǎn)速度為轉(zhuǎn)速加球速。

          設(shè)球向上的分速度v0 = 2m/s.a點(diǎn)對(duì)于地面的速度為 v0+v2 = 5.768m/s .如果靠摩擦把球拉起,拍速必須大于a點(diǎn)速度。約21公里/小時(shí)。

          2、拉下降期,a點(diǎn)速度為轉(zhuǎn)速減球速。

          設(shè)球向下落的分速度v0 = 2m/s.a點(diǎn)對(duì)于地面的速度為 v0-v2 = 1.768m/s .如果靠摩擦把球拉起,拍速必須大于a點(diǎn)速度。約6.3公里/小時(shí)。

          可見(jiàn)拉上升期比下降期需要三倍的速度!

           

           

          posted @ 2008-03-08 01:19 hk2000c 閱讀(1003) | 評(píng)論 (0)編輯 收藏

             我們?cè)趩挝焕镎{(diào)試用戶(hù)系統(tǒng)時(shí),單位的網(wǎng)絡(luò)地址一般和用戶(hù)的網(wǎng)絡(luò)地址不在一個(gè)網(wǎng)段上,如果沒(méi)有路由器則兩網(wǎng)不能互通,那對(duì)工作會(huì)很有影響。硬路由器價(jià)格昂貴也沒(méi)有必要去配,因?yàn)镾OLARIS可以很容易地設(shè)成軟件路由器,而不需另外花費(fèi)。

            1、編輯文件/etc/hosts,為該工作站加另一個(gè)網(wǎng)段地址:

             #vi/etc/hosts

             127.0.0.1localhost

             192.9.200.1serverloghost;本例的主機(jī)名及地址

             192.9.201.1 anoserver;另一個(gè)對(duì)應(yīng)的名稱(chēng)及地址

            2、編輯文件/etc/nerworks,將兩個(gè)網(wǎng)絡(luò)的地址加入:

             #vi /etc/networks

             loc 192.9.200;本網(wǎng)網(wǎng)址

             ano 192.9.201;另一個(gè)網(wǎng)的網(wǎng)址

            3、新建文件/etc/gateways,該文件只要存在沒(méi)有內(nèi)容也可,以使SOLARIS在啟動(dòng)時(shí)運(yùn)行路由器服務(wù)進(jìn)程。

             #cat/dev/null>/etc/gateways

            4、查詢(xún)主網(wǎng)卡的名稱(chēng):

             #ifconfig-a;列出系統(tǒng)中的所有網(wǎng)絡(luò)接口

             loO:flags=849<UP,LOOPBACK,RUN-NONG,MULTICAST>mtu 8232

             inet 127.0.0.1 netmask

             ff000000

             hneO:flags=863<UP,BROADCAST,NO-TRAILRS,RUNNNHG,MULTICAST>mtu1500

             inet 192.2.200.1 netmask ffffff00 broadcast

             192.2.200.255

             ether 8:0:20:1:2:3

             hme即為工作站上所配的100M網(wǎng)卡名,如果你所用的是10M網(wǎng)卡則名為le。

            5、新建文件/etc/hostname.hme0:1,將/etc/josts中的另一個(gè)主機(jī)名填入,以使SOLARIS啟動(dòng)時(shí)在物理接口hme0上建立一個(gè)邏輯接口。

            6、設(shè)置完以上各步后,重啟工作站

            7、效果:

             在工作站啟動(dòng)中,可以看到“machine is a router.”的噗顯示。表明本機(jī)已成為一個(gè)路由器,會(huì)向網(wǎng)絡(luò)上發(fā)RIP包,用接口查詢(xún)命令可見(jiàn):

             #ifcofig -a ;列出系統(tǒng)中的所有網(wǎng)絡(luò)接口

             lo0:flags=849<UP,LOOPBACK,RUNNNG,MULTICAST> mtu8232

             inet 127.0.0 .1etmask ff00000

             hne0:flags=863<UP,BROADCAST,NOTRAILERS,RUN-NING,MULTICAST>mtu 1500

             inet 192.9.200.1 netmask ffff00 broadcast

             192.9.200.255

             hne0:1:flags=8d0<UP,BROADCAST,NOTRAULERS,RUMNNNG,MULTICAST>mtu 1500

             inet 192.9.201.1 netmask ffff00 broadcast

             192.9.201.255

            以上表明已啟動(dòng)了hme0上的一個(gè)邏輯接口,地址為192.9.201.1。

            在別的UNIX機(jī)器上,會(huì)根據(jù)RIP包自動(dòng)將該工作站加入到路由表中,在PC機(jī)上(例如WIN95),只要在控制面板中將TCP/IPM網(wǎng)絡(luò)的網(wǎng)關(guān)設(shè)置為該工作站的地址(使用與本機(jī)同一個(gè)網(wǎng)絡(luò)的地址),就可以與另一網(wǎng)絡(luò)的機(jī)器通迅了。
          posted @ 2008-03-05 16:36 hk2000c 閱讀(454) | 評(píng)論 (0)編輯 收藏

          乓球意識(shí),是指運(yùn)動(dòng)員在乒乓球教學(xué)訓(xùn)練和比賽中的一種具有明確目的性和方向性的自覺(jué)的心理活動(dòng)。乒乓球意識(shí)的最顯著特點(diǎn)是它的能動(dòng)性。
            近年來(lái),意識(shí)一詞的使用日趨廣泛,如:“樹(shù)立首都意識(shí)”、“樹(shù)立奧運(yùn)意識(shí)”等。這里所說(shuō)的意識(shí)概念,和我們乒乓球運(yùn)動(dòng)中所說(shuō)的意識(shí)概念是一致的。就是要你想到北京是祖國(guó)的首都,想到奧運(yùn)會(huì),并以此來(lái)指導(dǎo)我們的思想和行動(dòng)。
            這樣,意識(shí)又可以理解為是一個(gè)思路或觀點(diǎn),它只是讓你自覺(jué)地想著這個(gè)問(wèn)題。至于怎樣想、用什么方法去解決這個(gè)問(wèn)題哪是技術(shù)問(wèn)題。以判斷意識(shí)為例,它只是要運(yùn)動(dòng)員想著判斷球,注意區(qū)別來(lái)球的不同特點(diǎn)。至于怎樣判斷來(lái)球,那是技術(shù)方法問(wèn)題,不屬判斷意識(shí)的范疇了。如有人打球時(shí),不看對(duì)方打的是什么球,一律愣頭愣腦地抽,結(jié)果失誤頻頻。這是缺乏判斷意識(shí)的典型表現(xiàn)。另一人懂得應(yīng)該判斷對(duì)方來(lái)球,實(shí)踐中也在緊緊地盯著球,但由于對(duì)方發(fā)球質(zhì)量高,結(jié)果接發(fā)球時(shí)還是“吃”了。這就不是判斷意識(shí)的問(wèn)題,而是還未掌握好接發(fā)球的方法。
            科學(xué)意識(shí)。一般人都能打乒乓球,但卻不是誰(shuí)都能打好。乒乓球運(yùn)動(dòng)有其自身的客觀規(guī)律。欲打好,則必須使自己的行為和心理符合乒乓球運(yùn)動(dòng)的客觀規(guī)律。為此,我們必須不斷地總結(jié)自己和他人的訓(xùn)練和比賽經(jīng)驗(yàn),不斷地學(xué)習(xí)科學(xué)文化知識(shí)(采用時(shí)代可能提供的先進(jìn)思想和先進(jìn)的科學(xué)技術(shù)方法、手段),不斷地探求乒乓球運(yùn)動(dòng)的規(guī)律,并用這些規(guī)律來(lái)指導(dǎo)自己的實(shí)踐。
            苦練與巧練相結(jié)合的意識(shí)。沒(méi)有一名優(yōu)秀的乒乓球運(yùn)動(dòng)員是不苦練的,但卻不是所有苦練者都能成為優(yōu)秀運(yùn)動(dòng)員。乒乓球運(yùn)動(dòng)有其自身的規(guī)律,只有當(dāng)人們的行動(dòng)符合其規(guī)律時(shí),才能獲得成功。探索規(guī)律,并用此來(lái)指導(dǎo)自己,這就是巧。所以,誰(shuí)要想打好乒乓球,就必須苦練與巧練相結(jié)合。沒(méi)有巧練的苦練,是傻練,甚至在一定意義上可說(shuō)是白練;沒(méi)有苦練做基礎(chǔ)的巧練,也稱(chēng)不上是巧,因?yàn)樗`反了訓(xùn)練的最基本規(guī)律。
            立志意識(shí)。志向,是一種巨大的力量,它能使人產(chǎn)生堅(jiān)強(qiáng)的意志和毅力,推動(dòng)人們的實(shí)踐活動(dòng)。志向總是同毅力相伴而行。一名運(yùn)動(dòng)員沒(méi)有堅(jiān)定不移的志向,就不可能有堅(jiān)強(qiáng)的意志和毅力,也就不可能實(shí)現(xiàn)自己的志向。少兒學(xué)打乒乓球,一般多從興趣開(kāi)始,而教練員則應(yīng)隨其進(jìn)步不斷地培養(yǎng)他們立志的意識(shí)。否則,就會(huì)如同古人所云:“志不立,天下無(wú)可成之事。”

            判斷意識(shí)。對(duì)付不同的來(lái)球,應(yīng)用不同的打法。若想打好球,首先應(yīng)對(duì)來(lái)球作出及時(shí)、準(zhǔn)確的判斷。這是正確還擊來(lái)球的前提。
            盯球意識(shí)。盯球,是正確判斷的基礎(chǔ)。不少人對(duì)來(lái)球判斷不及時(shí)或錯(cuò)誤,都是因?yàn)槎⑶虿粔颉_\(yùn)動(dòng)員每打完一板球后,都應(yīng)隨球密切注視對(duì)方擊球的動(dòng)作(尤其是擊球瞬間的動(dòng)作),并緊盯對(duì)方擊出球的弧線。
            移步意識(shí)。對(duì)方來(lái)球落點(diǎn)和節(jié)奏不定,為確保在最佳的位置和時(shí)間擊球,或最大限度地發(fā)揮個(gè)人的特長(zhǎng)技術(shù)(如反手位用側(cè)身攻),必須移步擊球。應(yīng)明確,打乒乓球絕不是單純的手法問(wèn)題,隨技術(shù)水平的提高,腳步移動(dòng)的重要性將越來(lái)越明;顯、它是爭(zhēng)取主動(dòng)、搶先進(jìn)攻的有力保證。

            探索合理?yè)羟螯c(diǎn)位置的意識(shí)。所謂的擊球點(diǎn)位置,即擊球點(diǎn)與身體的相對(duì)位置。各種技術(shù)動(dòng)作,都有一個(gè)最適宜的擊球位置。它雖有個(gè)一般的規(guī)律,但因人而宜十分重要。所以,運(yùn)動(dòng)員在打球的實(shí)踐中必須不斷地琢磨與研究自己擊球時(shí)最適宜的位置…
            打、摩結(jié)合意識(shí)。打乒乓球有兩個(gè)最基本的力,一個(gè)是撞擊球的力,簡(jiǎn)稱(chēng)為打;另一個(gè)是摩擦球之力,簡(jiǎn)稱(chēng)為摩。除近網(wǎng)大高球,可以用單純的打外,打其它的球,都必須是打與摩的結(jié)合。細(xì)究起來(lái),這里還有兩層意思。
            1、快抽時(shí),以打?yàn)橹鳎Σ翞檩o。打,可增加球的速度和力量;摩,可使球產(chǎn)生上旋,上旋有利于制造合理的擊球弧線。
            2、制造旋轉(zhuǎn)時(shí)(如拉弧圈球),應(yīng)以摩擦球?yàn)橹鳌5且晃蹲非竽Σ粒瑒?shì)必物極必反。擦球太薄,反而用不上力,自然難以打出旋轉(zhuǎn)強(qiáng)烈的球來(lái)。應(yīng)先打后摩,即以打的動(dòng)作將球近似粘于拍面,然后再加力摩擦。
            調(diào)節(jié)意識(shí)。無(wú)論哪種技術(shù)動(dòng)作,在還擊不同性能的來(lái)球時(shí),都必須自覺(jué)地調(diào)節(jié)動(dòng)作。具體可細(xì)分為:
            1、力量調(diào)節(jié)意識(shí):根據(jù)來(lái)球情況,適當(dāng)調(diào)節(jié)自己的發(fā)力。來(lái)球慢且高,發(fā)大力;攻對(duì)方搓過(guò)來(lái)的下旋球,自己發(fā)力為主,稍借對(duì)方來(lái)球之力;對(duì)方拉沖不特別兇、球略向前拱時(shí),借力中發(fā)力;對(duì)方發(fā)力抽或沖時(shí),自己應(yīng)借力擋一板或?qū)Ω兑话澹灰税l(fā)大力。
            2、拍形調(diào)節(jié)意識(shí):應(yīng)視來(lái)球旋轉(zhuǎn)與高低,適當(dāng)調(diào)節(jié)拍形。來(lái)球低或帶強(qiáng)烈下旋時(shí),拍形稍后仰;來(lái)球不轉(zhuǎn)或與可網(wǎng)高時(shí),拍形與臺(tái)面垂直;來(lái)球上旋或高于球時(shí),拍形前傾;
            3、引拍調(diào)節(jié)意識(shí):應(yīng)視來(lái)球的快慢、高低、旋轉(zhuǎn)等變化,相應(yīng)調(diào)整引拍動(dòng)作的快慢、大小和高低,切忌習(xí)慣性引拍(即不看來(lái)球,打完一板球后就習(xí)慣地將球拍引至原來(lái)位置)。如,對(duì)方拉過(guò)強(qiáng)烈上旋的弧圈球來(lái),應(yīng)高手引拍,并及時(shí)向前迎球(不要等球,更不能有向后的拉拍動(dòng)作);對(duì)方來(lái)球下旋且低,應(yīng)低手引拍;對(duì)方來(lái)球很快,應(yīng)減小引拍動(dòng)作幅度,加快引拍速度;來(lái)球慢且高,應(yīng)適當(dāng)加大引拍幅度,以利加力抽殺。
            4、手指調(diào)節(jié)意識(shí):打乒乓球,無(wú)論身體何部位發(fā)力,最后都要通過(guò)手指作用于球拍。手指是身體發(fā)力時(shí)離球最近的部位,感覺(jué)最敏銳。在發(fā)力時(shí),手指有如長(zhǎng)鞭之梢兒,往往起到畫(huà)龍點(diǎn)睛的作用。尤其是在發(fā)球時(shí),觸球瞬間的技巧全在手腕、手指的發(fā)力上。
            5、調(diào)節(jié)用力方向意識(shí):打球時(shí),應(yīng)視不同來(lái)球,注意調(diào)節(jié)用力方向。如,攻下旋低球,應(yīng)多向上用力;攻不轉(zhuǎn)球,以向前打?yàn)橹鳎还ゴ蛏闲龔?qiáng)烈的加轉(zhuǎn)弧圈球時(shí),應(yīng)向前并稍向下用力。
            還原意識(shí)。每打完一板球后,應(yīng)迅速調(diào)整重心,將身體盡量還原至接近準(zhǔn)備姿勢(shì),以為還擊下一板球做好準(zhǔn)備。有些人因缺乏此意識(shí),打完一板球后,身體重心、手臂和球拍較長(zhǎng)時(shí)間地停留在結(jié)束動(dòng)作上,待對(duì)方將球還擊過(guò)來(lái),往往有來(lái)不及的感覺(jué)。
            體會(huì)擊球動(dòng)作的意識(shí)。每打一板球,都要對(duì)整個(gè)擊球動(dòng)作有清晰的肌肉感覺(jué)和表象,尤其是拍觸球瞬間的發(fā)力情況應(yīng)該清清楚楚。打丟一板球,應(yīng)立刻回憶動(dòng)作,哪兒錯(cuò)了?怎樣才算正確?隨著技術(shù)水平的提高,動(dòng)腦筋還應(yīng)越來(lái)越細(xì)。如攻球出界了,出界多少?剛才的擊球動(dòng)作為什么把球打出界這么遠(yuǎn)?有了這種意識(shí),練技術(shù)才會(huì)有收獲。否則,一點(diǎn)體會(huì)沒(méi)有,技術(shù)怎么能進(jìn)步?
            掌握擊球動(dòng)作實(shí)質(zhì)的意識(shí)。研究技術(shù)動(dòng)作,要注意它的外形,但尤為重要的是應(yīng)分析擊球動(dòng)作的實(shí)質(zhì)。擺速快、能發(fā)力、打摩結(jié)合好、命中率高、適應(yīng)來(lái)球的范圍廣(即能依打不同來(lái)球的要求相應(yīng)調(diào)整動(dòng)作),這樣的動(dòng)作,就是好動(dòng)作。

            擊球動(dòng)作的時(shí)空意識(shí)。分析技術(shù)動(dòng)作,應(yīng)從兩方面入手。一是時(shí)間節(jié)奏方面,如快帶弧圈,上升期擊球;攻打弧圈球,上升后期擊球;拉下旋球,下降期擊球。二是空間位置(或幾何圖形的變化)。如揮拍路線、拍形、用力方法等。在時(shí)間節(jié)奏上,還要特別講究從引拍到向前揮拍擊球這段時(shí)間與來(lái)球的節(jié)奏合拍,這樣才能打出又快又狠的球來(lái)。即在自己發(fā)力的同時(shí),又充分借用了對(duì)方來(lái)球之力。研究與掌握這個(gè)節(jié)奏非常重要。
            動(dòng)作不斷分化的意識(shí)。在技術(shù)訓(xùn)練中,應(yīng)不斷將對(duì)方的來(lái)球總結(jié)分類(lèi),并明確回?fù)裘恳活?lèi)來(lái)球的方法和注意事項(xiàng)。不少運(yùn)動(dòng)員樂(lè)于打順手球,來(lái)球突變,失誤一球,甚為不快。其實(shí),這時(shí)應(yīng)好好想想,此球與順手球有什么不同,長(zhǎng)了、短了?旋轉(zhuǎn)強(qiáng)了?還是節(jié)奏變了?弄清楚此球特點(diǎn),繼而明確打此類(lèi)球的方法。這樣不斷將對(duì)方來(lái)球區(qū)分、歸類(lèi),并明確打每一類(lèi)球的不同方法,就可以使自己的技術(shù)越來(lái)越精細(xì),水平亦越來(lái)越高。
            動(dòng)作定與變的辯證意識(shí)。來(lái)球變了,打球動(dòng)作應(yīng)隨之而變;但打同類(lèi)球的動(dòng)作,則是越固定越好。掌握與提高技術(shù)的整個(gè)過(guò)程是,對(duì)來(lái)球的區(qū)分越來(lái)越細(xì),相應(yīng)打球的動(dòng)作也越分化越細(xì);但打同類(lèi)球的動(dòng)作,又越來(lái)越固定。這“固定”與“變化”的統(tǒng)一,就促進(jìn)了技術(shù)水平的不斷提高。
            戰(zhàn)術(shù)意識(shí)。實(shí)踐中有兩層含義。一是注意研究在比賽中運(yùn)用戰(zhàn)術(shù)的方法。因?yàn)橹挥泻侠淼剡\(yùn)用戰(zhàn)術(shù),才能使技術(shù)充分發(fā)揮。二是在訓(xùn)練中應(yīng)帶著戰(zhàn)術(shù)意識(shí)練技術(shù)。拿最簡(jiǎn)單的右方斜線對(duì)攻作例。有人在練習(xí)右斜對(duì)攻時(shí),能把比賽中的打大角和攻追身的戰(zhàn)術(shù)聯(lián)系起來(lái),有意打大角度或時(shí)而打?qū)Ψ街新芬话濉A硪蝗酥皇且晃兜孛つ抗バ本€。很明顯,前者帶著戰(zhàn)術(shù)意識(shí)練習(xí)技術(shù)的效果要好。
            戰(zhàn)略意識(shí)。在訓(xùn)練中,尤其是在比賽中,要有一個(gè)全局觀念。如一年中有幾次比賽?哪個(gè)比賽最重要?每個(gè)比賽的目的和任務(wù)都是什么?有時(shí)為參加某次有決定意義的大賽,還會(huì)有意放棄一些小的比賽。又如,對(duì)參加一次大賽而言,確立參賽人員和明確重點(diǎn)突破口(是團(tuán)體、單打,還是雙打?),則屬帶全局性的戰(zhàn)略問(wèn)題,必須認(rèn)真對(duì)待。如果這些大題目未解決好,盡管你費(fèi)了很大的氣力,其結(jié)果也難以如愿。
            落點(diǎn)意識(shí)。訓(xùn)練中,特別是在比賽中,要注意擊球的落點(diǎn)。一般情況下,大角度球、追身球、近網(wǎng)小球、底線長(zhǎng)球和似出臺(tái)未出臺(tái)的球的落點(diǎn)較好。但不同對(duì)手,還會(huì)因其打法和個(gè)人掌握技術(shù)的情況,有其特殊點(diǎn)。如左推右攻者,一般最怕反手底線下旋球和調(diào)右壓左的落點(diǎn)變化。比賽中,既要研究自己打球的落點(diǎn),對(duì)方最怕什么落點(diǎn),又要注意總結(jié)對(duì)方回球落點(diǎn)的規(guī)律。
            旋轉(zhuǎn)意識(shí)。充分認(rèn)識(shí)到旋轉(zhuǎn)是乒乓球的重要制勝因素之一。在訓(xùn)練中,要自覺(jué)地提高發(fā)球、搓球、拉球、放高球等技術(shù)的旋轉(zhuǎn)強(qiáng)度和變化。在比賽中,要善于利用旋轉(zhuǎn)變化來(lái)擾亂以至戰(zhàn)勝對(duì)方。
            速度意識(shí)。應(yīng)充分認(rèn)識(shí)到速度是我國(guó)快攻打法的靈魂。中國(guó)選手要戰(zhàn)勝外國(guó)選手,主要靠的仍是速度——提早擊球時(shí)間,重視手腕、手指的力量,能快則快,不能快時(shí),先過(guò)渡一板,爭(zhēng)取機(jī)會(huì)再轉(zhuǎn)入快。
            變化意識(shí)。應(yīng)充分認(rèn)識(shí)到變化乃是乒乓球的重要制勝因素之一,自覺(jué)、主動(dòng)地變化擊球的速度、旋轉(zhuǎn)、力量、落點(diǎn)和弧線。比賽中,雙方都在為形成利我、不利對(duì)方的戰(zhàn)局而變化著戰(zhàn)術(shù),誰(shuí)的觀察能力強(qiáng),能及時(shí)察覺(jué)對(duì)方的戰(zhàn)術(shù)意圖,迅速變換相應(yīng)的戰(zhàn)術(shù),誰(shuí)就容易獲取勝利。
            變化擊球節(jié)奏的意識(shí)。比賽中,不僅應(yīng)主動(dòng)變化落點(diǎn)、旋轉(zhuǎn)等,而且應(yīng)主動(dòng)變化擊球的節(jié)奏。如原來(lái)都是上升或高點(diǎn)期的搶沖,現(xiàn)主動(dòng)將擊球時(shí)間后移,拉一板上旋強(qiáng)烈的加轉(zhuǎn)弧圈球。對(duì)方已熟悉了你原來(lái)快沖的節(jié)奏,突然變成慢一拍的加轉(zhuǎn)弧圈,往往就會(huì)上當(dāng),又如,同一類(lèi)發(fā)球,有節(jié)奏較慢的,有節(jié)奏特快的,若再能保持拍觸球前的動(dòng)作盡量一致,則效果更好,這都是有變化節(jié)奏意識(shí)的表現(xiàn)。
            搶攻意識(shí)。這是積極主動(dòng)的指導(dǎo)思想,力爭(zhēng)搶攻在先(即平常說(shuō)的先上手),能搶則搶、實(shí)在不能搶時(shí),控制一板,爭(zhēng)取下板搶。這種意識(shí)很重要。如有人的側(cè)身攻球技術(shù)很不錯(cuò),但就因缺乏搶攻意識(shí),所以使他的側(cè)身攻球技術(shù)英雄無(wú)用武之地。兵書(shū)講:“兩強(qiáng)相遇,勇者勝。”這“勇”字的一個(gè)重要含義就是先發(fā)制人。在弧圈球風(fēng)靡世界的今天,快攻者只搓一板就攻攻的打法,即是搶攻意識(shí)強(qiáng)的表現(xiàn)。
            搶先發(fā)力的意識(shí)。近年來(lái),世界乒乓球技術(shù)朝著更加積極主動(dòng)的方向發(fā)展,不僅要求搶攻在先,而且應(yīng)該盡量爭(zhēng)取先發(fā)力,以使自己更加主動(dòng)。
            連續(xù)進(jìn)攻的意識(shí)。發(fā)起進(jìn)攻后,應(yīng)連續(xù)進(jìn)攻,乘勝追擊,直至得分。切忌攻一板后,再無(wú)繼續(xù)進(jìn)攻的準(zhǔn)備,將已到手的主動(dòng)又變成了相持、甚至被動(dòng)。
            控、防、反意識(shí)。在不能主動(dòng)進(jìn)攻或?qū)Ψ綋尮ヒ庾R(shí)極強(qiáng)時(shí),應(yīng)注意控制對(duì)方,并做好防守的準(zhǔn)備。在防守或相持中,一旦有機(jī)會(huì),應(yīng)立即轉(zhuǎn)入進(jìn)攻。
            爭(zhēng)取局部?jī)?yōu)勢(shì)的意識(shí)。我的所有技術(shù)都比對(duì)方強(qiáng),這叫絕對(duì)優(yōu)勢(shì)。比賽中自然怎么打都行。但在實(shí)踐中,這種情況比較少見(jiàn)。多數(shù)情況是相對(duì)優(yōu)勢(shì)。這就要求運(yùn)動(dòng)員在比賽中應(yīng)自覺(jué)地爭(zhēng)取局部?jī)?yōu)勢(shì)。能以己之長(zhǎng),打?qū)Ψ街蹋?dāng)然最好。但有時(shí)不一定能實(shí)現(xiàn)此策。如,我發(fā)球的特長(zhǎng)是轉(zhuǎn)與不轉(zhuǎn),而對(duì)方的特短是接高拋發(fā)球。我之特長(zhǎng)對(duì)不上對(duì)方的特短。高拋發(fā)球雖為我之特短,但與對(duì)方接此球相比,我還占便宜。此時(shí)用我之特短打?qū)Ψ教囟叹褪亲詈玫膽?zhàn)術(shù)。因?yàn)槲耀@得了局部?jī)?yōu)勢(shì)。
            記球意識(shí)。比賽時(shí),要有意記雙方戰(zhàn)術(shù)變化的過(guò)程,對(duì)方發(fā)的什么球,我怎么回的,他又怎么打的……從一個(gè)球,到整個(gè)戰(zhàn)局的變化,要自覺(jué)地記。時(shí)間長(zhǎng)了,就會(huì)大大提高自己的戰(zhàn)術(shù)意識(shí)。
            互怕意識(shí)。比賽中“怕”是相互的。你怕他,他也怕你。誰(shuí)能透過(guò)現(xiàn)象看到本質(zhì),誰(shuí)能想得好一點(diǎn),誰(shuí)就容易主動(dòng)。在緊張時(shí),應(yīng)多想對(duì)自己有利的方面,多想對(duì)方是多么怕你,多想戰(zhàn)術(shù),這樣就可以長(zhǎng)自己志氣,滅對(duì)方威風(fēng)。
            戰(zhàn)略上藐視對(duì)手、戰(zhàn)術(shù)上重視對(duì)手的意識(shí)。戰(zhàn)略者,戰(zhàn)爭(zhēng)的全局也;戰(zhàn)術(shù)者,戰(zhàn)爭(zhēng)的局部也。運(yùn)動(dòng)員應(yīng)樹(shù)立在全局或總體上藐視對(duì)手、藐視困難,而在具體的局部上應(yīng)重視對(duì)手、重視困難的指導(dǎo)思想。如對(duì)某某比賽,首先應(yīng)相信自己能戰(zhàn)勝對(duì)方,并認(rèn)真地分析對(duì)手的技術(shù)、戰(zhàn)術(shù)、身體和心理特點(diǎn)。在此基礎(chǔ)上制訂自己的戰(zhàn)術(shù),如發(fā)什么球,怎么搶攻,接發(fā)球注意什么,相持、領(lǐng)先或落后怎么打等等,一步一步、詳詳細(xì)細(xì)。
            樹(shù)立技術(shù)風(fēng)格的意識(shí)。在技、戰(zhàn)術(shù)訓(xùn)練中、應(yīng)特別強(qiáng)調(diào)樹(shù)立正確的技術(shù)風(fēng)格。技術(shù)風(fēng)格,常被喻為運(yùn)動(dòng)員的技術(shù)“靈魂”。培養(yǎng)什么樣的技術(shù)風(fēng)格,將直接關(guān)系到運(yùn)動(dòng)員的發(fā)展方向和可能達(dá)到的水平。無(wú)數(shù)事實(shí)證明,一個(gè)沒(méi)有鮮明技術(shù)風(fēng)格的選手,要攀登世界乒壇的高峰是不可能的!
            全面訓(xùn)練的意識(shí)。運(yùn)動(dòng)員應(yīng)明確決定其競(jìng)技能力的諸因素(形態(tài)、機(jī)能、素質(zhì)、技術(shù)、戰(zhàn)術(shù)、心理和智力等),并自覺(jué)地提高之。這里,應(yīng)反對(duì)狹隘的技術(shù)論。有人以為,要提高乒乓球運(yùn)動(dòng)成績(jī),就應(yīng)該全力抓技術(shù),什么身體素質(zhì)、心理等統(tǒng)統(tǒng)不問(wèn)。結(jié)果,盡管訓(xùn)練時(shí)間練的都是技術(shù),但技術(shù)水平的提高卻難以如愿。運(yùn)動(dòng)員一定要樹(shù)立全面訓(xùn)練的觀點(diǎn)。
            抓主要矛盾的意識(shí)。每一名運(yùn)動(dòng)員在某一時(shí)期必有一個(gè)主要矛盾影響著他整體水平的提高。誰(shuí)善于捕捉之,并設(shè)法解決,誰(shuí)就會(huì)獲得明顯的進(jìn)步。如中國(guó)乒乓隊(duì)在1957年參加第二十三屆世乒賽后,發(fā)現(xiàn)自己的打法因缺乏準(zhǔn)確性而使快速、兇狠的優(yōu)點(diǎn)難以發(fā)揮作用。之后,狠抓了提高擊球準(zhǔn)確性的訓(xùn)練,很快就見(jiàn)到了明顯的效果。不善于抓主要矛盾的人,不是漫無(wú)邊際,什么都抓,就是雖有重點(diǎn),但抓得不準(zhǔn)。其結(jié)果都是一樣——費(fèi)力不討好!
            兇穩(wěn)結(jié)合的意識(shí)。乒乓球的技術(shù)各種各樣,每個(gè)人的打法又各具特點(diǎn),但凡在比賽中有實(shí)用價(jià)值的技術(shù),無(wú)不同時(shí)具備威脅性(兇)和準(zhǔn)確性(穩(wěn))。威脅性,即打出的球給對(duì)方回球造成困難,甚至使對(duì)方失誤。準(zhǔn)確性,即擊球不失誤。二者相互依存,并在一定的條件下可以互相轉(zhuǎn)化。我們?cè)谟?xùn)練或比賽中,一定要注意二者的結(jié)合,決不可以偏蓋全。
            練絕招的意識(shí)。一個(gè)運(yùn)動(dòng)員的技術(shù)一定要有特長(zhǎng),即絕招,否則往往難以給對(duì)方造成威脅,也難以攀登技術(shù)高峰。絕招,可根據(jù)個(gè)人打法的特點(diǎn)、身體素質(zhì)的特點(diǎn)、心理特點(diǎn)和所用球拍的性能等因素有目的地確立。“傷其十指,不如斷其一指。”絕招就是起碼能斷其一指的技術(shù)。
            表現(xiàn)意識(shí)。明確訓(xùn)練是為了比賽。運(yùn)動(dòng)員在平日訓(xùn)練就應(yīng)有一種要在比賽中強(qiáng)烈表現(xiàn)自己的欲望。這如同演員,排練節(jié)目就是為了上臺(tái)表演;不但要上臺(tái),還要演得呱呱叫。平時(shí)這種意識(shí)強(qiáng)烈,演出時(shí)才可能發(fā)揮出色。當(dāng)運(yùn)動(dòng)員亦是同樣道理。
            重視理論的意識(shí)。運(yùn)動(dòng)員應(yīng)充分認(rèn)識(shí)到理論對(duì)實(shí)踐的指導(dǎo)作用,自覺(jué)地學(xué)習(xí)和鉆研乒乓球運(yùn)動(dòng)的理論,并注意理論與實(shí)踐的結(jié)合。
            創(chuàng)新意識(shí),無(wú)論是教練員還是運(yùn)動(dòng)員,都要十分重視創(chuàng)新。乒乓球運(yùn)動(dòng)的創(chuàng)新,應(yīng)包括技術(shù)、戰(zhàn)術(shù)、打法、訓(xùn)練、管理、器材設(shè)備和理論等七個(gè)方面。運(yùn)動(dòng)員主要是前四個(gè)方面。
            超前意識(shí)。教練員和運(yùn)動(dòng)員應(yīng)能預(yù)測(cè)出未來(lái)的技術(shù)發(fā)展趨勢(shì),并以此來(lái)指導(dǎo)訓(xùn)練,使自己的訓(xùn)練能走在現(xiàn)實(shí)技術(shù)的前面。
            定量意識(shí)。運(yùn)動(dòng)員在訓(xùn)練或比賽中,應(yīng)自覺(jué)地注意數(shù)量的變化。如,1500米跑多少秒?其中的每一圈(400米)又跑幾秒?一周到底練多少時(shí)間?個(gè)人的競(jìng)技狀態(tài)周期規(guī)律是怎樣的?個(gè)人晨脈的規(guī)律是怎樣的?某技術(shù)在訓(xùn)練中的命中率是多少,比賽中又是多少?一場(chǎng)、一局比賽的比分起伏是怎樣的?切忌什么都是含含糊糊。
            檔案意識(shí)。教練員和運(yùn)動(dòng)員應(yīng)自覺(jué)地建立業(yè)務(wù)檔案,堅(jiān)持寫(xiě)好訓(xùn)練日記、階段小結(jié)及年終總結(jié)。每年比賽勝負(fù)各多少場(chǎng)?身體素質(zhì)或技術(shù)測(cè)驗(yàn)的具體成績(jī)是多少,都應(yīng)分門(mén)別類(lèi)記錄清楚。
          posted @ 2008-02-28 22:48 hk2000c 閱讀(329) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共11頁(yè): 1 2 3 4 5 6 7 8 9 下一頁(yè) Last 
          主站蜘蛛池模板: 玉山县| 奉贤区| 北京市| 木兰县| 常州市| 乐业县| 江陵县| 景谷| 修水县| 永善县| 阜新市| 泉州市| 榆树市| 南皮县| 无锡市| 香河县| 东莞市| 岳西县| 榆社县| 象州县| 木兰县| 平江县| 天峨县| 平安县| 抚远县| 清远市| 同仁县| 游戏| 昌图县| 敦化市| 巴南区| 曲水县| 东乡族自治县| 义乌市| 潜山县| 和林格尔县| 乐安县| 高碑店市| 剑川县| 湖州市| 台南市|