AOP作為Spring這個輕量級的容器中很重要的一部分,得到越來越多的關注,Spring的Transaction就是用AOP來管理的,今天就通過簡單的例子來看看Spring中的AOP的基本使用方法。 首先確定將要Proxy的目標,在Spring中默認采用JDK中的dynamic proxy,它只能夠實現接口的代理,如果想對類進行代理的話,需要采用CGLIB的proxy。顯然,選擇“編程到接口”是更明智的做法,下面是將要代理的接口: public interface FooInterface { public void printFoo(); public void dummyFoo(); } 以及其一個簡單的實現: public class FooImpl implements FooInterface { public void printFoo() { System.out.println("In FooImpl.printFoo"); } public void dummyFoo() { System.out.println("In FooImpl.dummyFoo"); } } 接下來創建一個Advice,在Spring中支持Around,Before,After returning和Throws四種Advice,這裡就以簡單的Before Advice舉例: public class PrintBeforeAdvice implements MethodBeforeAdvice { public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("In PrintBeforeAdvice"); } } 有了自己的business interface和advice,剩下的就是如何去裝配它們了,首先利用ProxyFactory以編程方式實現,如下: public class AopTestMain { public static void main(String[] args) { FooImpl fooImpl = new FooImpl(); PrintBeforeAdvice myAdvice = new PrintBeforeAdvice(); ProxyFactory factory = new ProxyFactory(fooImpl); factory.addBeforeAdvice(myAdvice); FooInterface myInterface = (FooInterface)factory.getProxy(); myInterface.printFoo(); myInterface.dummyFoo(); } } 現在執行程序,神奇的結果就出現了: In PrintBeforeAdvice In FooImpl.printFoo In PrintBeforeAdvice In FooImpl.dummyFoo 雖然這樣能體會到Spring中AOP的用法,但這決不是值得推薦的方法,既然使用了Spring,在ApplicationContext中裝配所需要 的bean才是最佳策略,實現上面的功能只需要寫個簡單的applicationContext就可以了,如下: The aop application context
FooInterface
myAdvice
當然,main中的代碼也要進行相應的修改: public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.XML"); FooInterface foo = (FooInterface)context.getBean("foo"); foo.printFoo(); foo.dummyFoo(); } 現在運行一下,結果將和上面的運行結果完全一樣,這樣是不是更優雅?當需要更改實現時,只需要修改配置文件就可以了,程序中的代碼不需任何改動。 但是,這時候會發現被proxy的object中的所有方法調用時都將運行advice中的before,這顯然不能滿足絕大多數情況下的需要,此時,只 需借用Advisor就可以了,當然要在Advisor中利用pattern設置好哪些方法需要advice,更改applicationContext 如下: The springeva application context
.*print.*
FooInterface
myAdvisor
主程序不需進行任何修改,運行結果已經變樣了: In PrintBeforeAdvice In FooImpl.printFoo In FooImpl.dummyFoo 至此,應該已經理解了Spring中AOP的使用方法,當然Spring中AOP最重要的應用是Transaction Manager,舉個這方面的applicationContext例子看看:
/WEB-INF/jdbc.propertIEs
${jdbc.driverClassName}
${jdbc.url}
${jdbc.username}
${jdbc.passWord}
smartmenu.hbm.XML
${hibernate.dialect}
PROPAGATION_REQUIRED,readOnly
PROPAGATION_REQUIRED,readOnly
嗯,要想徹底理解Spring的AOP,最好還是多看看源碼,開源就是好啊!