軟件藝術(shù)思考者  
          混沌,彷徨,立志,蓄勢...
          公告
          日歷
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          隨筆分類(86)

          隨筆檔案(85)

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           
          SpringFramework中的AOP簡單使用
          AOP作為Spring這個輕量級的容器中很重要的一部分,得到越來越多的關(guān)注,Spring的Transaction就是用AOP來管理的,今天就通過簡單的例子來看看Spring中的AOP的基本使用方法。

          ? 首先確定將要Proxy的目標(biāo),在Spring中默認(rèn)采用JDK中的dynamic proxy,它只能夠?qū)崿F(xiàn)接口的代理,如果想對類進行代理的話,需要采用CGLIB的proxy。顯然,選擇“編程到接口”是更明智的做法,下面是將要代理的接口:

          ? public interface FooInterface {
          ??? public void printFoo();
          ??? public void dummyFoo();
          ? }

          ?
          ? 以及其一個簡單的實現(xiàn):
          ?
          ? public class FooImpl implements FooInterface {
          ??? public void printFoo() {
          ????? System.out.println("In FooImpl.printFoo");
          ??? }
          ??? public void dummyFoo() {
          ????? System.out.println("In FooImpl.dummyFoo");
          ??? }
          ? }

          ?
          ? 接下來創(chuàng)建一個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以編程方式實現(xiàn),如下:
          ?
          ? 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();
          ??? }
          ? }
          ?
          ? 現(xiàn)在執(zhí)行程序,神奇的結(jié)果就出現(xiàn)了:
          ?
          ? In PrintBeforeAdvice
          ? In FooImpl.printFoo
          ? In PrintBeforeAdvice
          ? In FooImpl.dummyFoo

          ?
          ? 雖然這樣能體會到Spring中AOP的用法,但這決不是值得推薦的方法,既然使用了Spring,在ApplicationContext中裝配所需要 的bean才是最佳策略,實現(xiàn)上面的功能只需要寫個簡單的applicationContext就可以了,如下:
          ?
          ? <?xml version="1.0" encoding="UTF-8"?>
          ? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
          ??? "
          http://www.springframework.org/dtd/spring-beans.dtd">

          ? <beans>
          ??? <description>The aop application context</description>
          ??? <bean id="fooTarget" class="FooImpl"/>
          ??? <bean id="myAdvice" class="PrintBeforeAdvice"/>
          ?? ?<bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
          ???? <property name="proxyInterfaces">
          ?????? <value>FooInterface</value>
          ???? </property>
          ?????<property name="target">
          ?????? <ref local="fooTarget"/>
          ???? </property>
          ???? <property name="interceptorNames">
          ?????? <list>
          ???????? <value>myAdvice</value>
          ?????? </list>
          ???? </property>
          ??? </bean>
          ? </beans>

          ? 當(dāng)然,main中的代碼也要進行相應(yīng)的修改:
          ????
          ? public static void main(String[] args) {
          ??? ClassPathXmlApplicationContext context = new?
          ?????????????ClassPathXmlApplicationContext("applicationContext.xml");
          ??? FooInterface foo = (FooInterface)context.getBean("foo");
          ??? foo.printFoo();
          ??? foo.dummyFoo();
          ? }

          ?
          ? 現(xiàn)在運行一下,結(jié)果將和上面的運行結(jié)果完全一樣,這樣是不是更優(yōu)雅?當(dāng)需要更改實現(xiàn)時,只需要修改配置文件就可以了,程序中的代碼不需任何改動。
          ?
          ? 但是,這時候會發(fā)現(xiàn)被proxy的object中的所有方法調(diào)用時都將運行advice中的before,這顯然不能滿足絕大多數(shù)情況下的需要,此時,只 需借用Advisor就可以了,當(dāng)然要在Advisor中利用pattern設(shè)置好哪些方法需要advice,更改applicationContext 如下:
          ?
          ? <?xml version="1.0" encoding="UTF-8"?>
          ? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
          ??? "
          http://www.springframework.org/dtd/spring-beans.dtd">

          ? <beans>
          ??? <description>The springeva application context</description>
          ?? ?<bean id="fooTarget" class="FooImpl"/>
          ??? <bean id="printBeforeAdvice" class="PrintBeforeAdvice"/>
          ??? <bean id="myAdvisor"
          ????????? class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
          ????? <property name="advice">
          ??????? <ref local="printBeforeAdvice"/>
          ????? </property>
          ????? <property name="pattern">
          ??????? <value>.*print.*</value>
          ????? </property>
          ??? </bean>
          ??? <bean id="foo" class="org.springframework.aop.framework.ProxyFactoryBean">
          ????? <property name="proxyInterfaces">
          ????????<value>FooInterface</value>
          ????? </property>
          ????? <property name="target">
          ??????? <ref local="fooTarget"/>
          ????? </property>
          ????? <property name="interceptorNames">
          ??????? <list>
          ????????? <value>myAdvisor</value>
          ??????? </list>
          ??????</property>
          ??? </bean>
          ? </beans>

          ? 主程序不需進行任何修改,運行結(jié)果已經(jīng)變樣了:

          ? In PrintBeforeAdvice
          ? In FooImpl.printFoo
          ? In FooImpl.dummyFoo

          ?
          ? 至此,應(yīng)該已經(jīng)理解了Spring中AOP的使用方法,當(dāng)然Spring中AOP最重要的應(yīng)用是Transaction Manager,舉個這方面的applicationContext例子看看:
          ?
          ? <?xml version="1.0" encoding="UTF-8"?>
          ? <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "spring-beans.dtd">

          ? <beans>
          ??? <bean id="propertyConfigurer"???
          ???????? class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
          ????? <property name="location">
          ??????? <value>/WEB-INF/jdbc.properties</value>
          ??????</property>
          ?? ?</bean>
          ??? <bean id="dataSource"
          ????????? class="org.springframework.jdbc.datasource.DriverManagerDataSource">
          ????? <property name="driverClassName">
          ??????? <value>${jdbc.driverClassName}</value>
          ????? </property>
          ??????<property name="url">
          ??????? <value>${jdbc.url}</value>
          ????? </property>
          ????? <property name="username">
          ??????? <value>${jdbc.username}</value>
          ????? </property>
          ????? <property name="password">
          ??????? <value>${jdbc.password}</value>
          ????? </property>
          ??? </bean>
          ?? ?<bean id="sessionFactory"
          ????????? class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
          ????? <property name="dataSource">
          ??????? <ref local="dataSource"/>
          ????? </property>
          ????? <property name="mappingResources">
          ??????? <value>smartmenu.hbm.xml</value>
          ????? </property>
          ????? <property name="hibernateProperties">
          ??????? <props>
          ????????? <prop key="hibernate.dialect">${hibernate.dialect}</prop>
          ??????? </props>
          ????? </property>
          ??? </bean>
          ?
          ??? <bean id="transactionManager"???????
          ????????? class="org.springframework.orm.hibernate.HibernateTransactionManager">
          ????? <property name="sessionFactory">
          ??????? <ref local="sessionFactory"/>
          ????? </property>
          ??? </bean>
          ??? <bean id="smartmenuTarget" class="SmartMenuHibernate">
          ????? <property name="sessionFactory">
          ??????? <ref local="sessionFactory"/>
          ????? </property>
          ??? </bean>
          ?? ?<bean id="smartMenu"
          ??????? class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          ????? <property name="transactionManager">
          ??????? <ref local="transactionManager"/>
          ????? </property>
          ????? <property name="target">
          ??????? <ref local="smartmenuTarget"/>
          ????? </property>
          ????? <property name="transactionAttributes">
          ??????? <props>
          ????????? <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
          ????????? <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
          ??????? </props>
          ????? </property>
          ??? </bean>
          ? </beans>

          ?
          ? 要想徹底理解Spring的AOP,最好還是多看看源碼,開源就是好??!

          posted on 2006-07-25 11:38 智者無疆 閱讀(429) 評論(1)  編輯  收藏 所屬分類: about spring
          評論:
           
          Copyright © 智者無疆 Powered by: 博客園 模板提供:滬江博客


             觀音菩薩贊

          主站蜘蛛池模板: 景谷| 霍城县| 龙陵县| 江城| 武夷山市| 渭南市| 深圳市| 新营市| 当涂县| 财经| 万源市| 永年县| 南陵县| 济宁市| 清新县| 望都县| 徐州市| 吉水县| 邓州市| 阳朔县| 通江县| 汝城县| 重庆市| 乌恰县| 阜康市| 遂宁市| 正阳县| 黑山县| 磐安县| 措勤县| 都江堰市| 宜阳县| 盖州市| 惠来县| 卓尼县| 古田县| 通城县| 瑞丽市| 天峻县| 策勒县| 奉贤区|