才開始學習AOP功能,並成功輸出了Hello World了,哈哈,成功邁出第一步。
在該例子中,我們先編寫一個類簡單輸出World,然後利用AOP,我們在程式運行時,讓這個類的執行個體輸出“Hello World!"。
代碼清單1:MessageWriter類
package com.enyes.heart.java.aop.simple;public class MessageWriter{ public void writeMessage() { System.out.print("World"); }}
MessageWriter類功能一眼明了。它只有一個列印World到控制台的輸出方法。我們打算增加一個通知給這個類,讓它的writeMessage()方法輸入”Hello World!“。
為了完整輸出Hello World,我們需要在這個方法之前輸出Hello,並在這個方法結束後輸出!。AOP術語解釋為:我們需要包圍通知(around Advice),即包圍連接點的通知。在這個執行個體中,連接點就是對writeMessage()方法的調用。如下MessageDecorator類實現包圍通知。
代碼清單2:MessageDecorator類。
package com.enyes.heart.java.aop.simple;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;public class MessageDecorator implements MethodInterceptor{ public Object invoke(MethodInvocation invocation) throws Throwable { System.out.print("Hello "); Object obj = invocation.proceed(); System.out.println("!"); return obj; } }
MethodInteceptor介面就是對方法調用連接點實現包圍通知的AOP標準介面。MethodInvocation對象表示當前被通知的方法調用。我們使用這個類來控制具體什麼時候進行方法調用,所以我們可以在方法調用之前進行邏輯操作,也可以在方法調用之後執行另外的操作。如上代碼清單中,我們簡單的輸出Hello,然後調用目標方法,然後輸入!。
最後將MessageDecorator通知織入代碼中。MessageWriter為目標對象,然後為其建立一個代理,並讓代理工廠(proxy Factory)織入MessageDecorator通知。
代碼清單3:具體MessageDecorator織入通知。
package com.enyes.heart.java.aop.simple;import org.springframework.aop.framework.ProxyFactory;public class HelloWorldWeaver{ public static void main(String[] args) { MessageWriter target = new MessageWriter(); ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.addAdvice(new MessageDecorator()); proxyFactory.setTarget(target); MessageWriter proxy = (MessageWriter)proxyFactory.getProxy(); target.writeMessage(); System.out.println(""); proxy.writeMessage(); }}
這裡,最終的部分是我們用ProxyFactory類來建立一個目標對象的代理,同時織入通知。我們通過調用addAdvice()方法將MessageDecorator通知傳給ProxyFactory,然後通過setTarget()方法設定織入的目標對象。設定好目標對象並加入了通知後,我們通過getProxy()方法獲得一個代理,然後使用代理調用目標方法。最後我們比較兩種不同方法的調用產生的結果。如下。
-------------------------------
WorldHello World!
--------------------------------
具體操作jar包支援如下說明:
1.aopalliance-1.0.jar AOP標準JAR
2.org.springframework.aop-3.1.2.RELEASE.jar Spring3.1.2 RELEASE版本的AOPjar,可在Spring官網下載完整jar包。
3.org.springframework.core-3.1.2.RELEASE.jar Spring核心包,AOP依賴該jar包。
4.commons-logging.jar Spring使用該包列印日誌。
5.com.springsource.net.sf.cglib-2.1.3.jar CGLIB代理。如果缺少該包,錯誤資訊如下:
Exception in thread "main" org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces.at org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy(DefaultAopProxyFactory.java:67)at org.springframework.aop.framework.ProxyCreatorSupport.createAopProxy(ProxyCreatorSupport.java:104)at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:98)at com.enyes.heart.java.aop.simple.HelloWorldWeaver.main(HelloWorldWeaver.java:15)
註:非cglib-2.1_3.jar包,如果使用該包,出錯資訊如下,然後你去尋找asm包。。。
Exception in thread "main" java.lang.NoClassDefFoundError: org/objectweb/asm/Typeat net.sf.cglib.core.TypeUtils.parseType(TypeUtils.java:180)at net.sf.cglib.core.KeyFactory.<clinit>(KeyFactory.java:66)at net.sf.cglib.proxy.Enhancer.<clinit>(Enhancer.java:69)at org.springframework.aop.framework.Cglib2AopProxy.createEnhancer(Cglib2AopProxy.java:229)at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:171)at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:146)at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:98)at com.enyes.heart.java.aop.simple.HelloWorldWeaver.main(HelloWorldWeaver.java:15)Caused by: java.lang.ClassNotFoundException: org.objectweb.asm.Typeat java.net.URLClassLoader$1.run(URLClassLoader.java:200)at java.security.AccessController.doPrivileged(Native Method)at java.net.URLClassLoader.findClass(URLClassLoader.java:188)at java.lang.ClassLoader.loadClass(ClassLoader.java:307)at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)at java.lang.ClassLoader.loadClass(ClassLoader.java:252)at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)... 8 more
另:jar可通過網站findjar快速尋找下載,不需要百度,在csdn使用積分下載,對於像我這樣毫無積分的人來說完全杯具。