一、一個簡單切面的配置java
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:before pointcut="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))" method="preGreeting"/> </aop:aspect> </aop:config> <bean id="adviceMethods" class="com.yyq.schema.AdviceMethods"/> <bean id="naiveWaiter" class="com.yyq.schema.NaiveWaiter"/> <bean id="naughtyWaiter" class="com.yyq.schema.NaughtyWaiter"/> </beans>
使用一個<aop:aspect>元素標籤訂義切面,其內部能夠定義多個加強。在<aop:config>元素中能夠定義多個切面。經過<aop:before>聲明瞭一個前置加強,並經過pointcut屬性定義切點表達式,切點表達式的語法和@AspectJ中所用的語法徹底相同,因爲&&在XML中使用不便,因此通常用and操做符代替。經過method屬性指定加強的方法,該方法應該是adviceMethods Bean中的方法。spring
package com.baobaotao.schema; import org.aspectj.lang.ProceedingJoinPoint; public class AdviceMethods { public void preGreeting(String name) { System.out.println("--how are you!--"); System.out.println(name); } //後置加強對應方法 public void afterReturning(int retVal){ System.out.println("----afterReturning()----"); System.out.println("returnValue:"+retVal); System.out.println("----afterReturning()----"); } //環繞加強對應方法 public void aroundMethod(ProceedingJoinPoint pjp){ System.out.println("----aroundMethod()----"); System.out.println("args[0]:"+pjp.getArgs()[0]); System.out.println("----aroundMethod()----"); } //拋出異常加強 public void afterThrowingMethod(IllegalArgumentException iae){ System.out.println("----afterThrowingMethod()----"); System.out.println("exception msg:"+iae.getMessage()); System.out.println("----afterThrowingMethod()----"); } //final加強 public void afterMethod(){ System.out.println("----afterMethod()----"); } //------------綁定鏈接點參數----------// public void bindParams(int num,String name){ System.out.println("----bindParams()----"); System.out.println("name:"+name); System.out.println("num:"+num); System.out.println("----bindParams()----"); } }
NaiveWaiter類:express
package com.yyq.schema; public class NaiveWaiter implements Waiter { @Override public void greetTo(String name) { System.out.println("NaiveWaiter:greet to " + name + "..."); } @Override public void serveTo(String name) { System.out.println("NaiveWaiter:serving to " + name + "..."); } public void smile(String clientName,int times){ System.out.println("NaiveWaiter:smile to "+clientName+ times+"times..."); } }
NaughtyWaiter類:ide
package com.yyq.schema; public class NaughtyWaiter implements Waiter { public void greetTo(String clientName) { System.out.println("NaughtyWaiter:greet to " + clientName + "..."); } public void serveTo(String clientName) { System.out.println("NaughtyWaiter:serving " + clientName + "..."); } public void joke(String clientName, int times) { System.out.println("NaughtyWaiter:play " + times + " jokes to " + clientName + "..."); } }
測試方法:函數
package com.yyq; import com.yyq.schema.Waiter; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SchemaTest { @Test public void schemaTest(){ String configPath = "com\\yyq\\schema\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter naiveWaiter = (Waiter)ctx.getBean("naiveWaiter"); Waiter naughtyWaiter = (Waiter)ctx.getBean("naughtyWaiter"); naiveWaiter.greetTo("John"); naughtyWaiter.greetTo("Tom"); } }
<aop:config proxy-target-class="true">
<aop:aspect ref="adviceMethods">
<aop:pointcut id="greetToPointcut" expression="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))"/>
<aop:before method="preGreeting" pointcut-ref="greetToPointcut"/>
</aop:aspect>
</aop:config>
使用<aop:pointcut>定義了一個切點,並經過id屬性進行命名,經過pointcut-ref引用這個命名的切點。和<aop:before>同樣,除了引介加強外,其餘任意加強類型都擁有pointcut、pointcut-ref和method這3個屬性。post
<aop:config proxy-target-class="true">
<aop:pointcut id="greetToPointcut2" expression="target(com.yyq.schema.NaiveWaiter) and execution(* greetTo(..))"/>
<aop:aspect ref="adviceMethods">
<aop:before method="preGreeting" pointcut-ref="greetToPointcut2"/>
</aop:aspect>
<aop:aspect ref="adviceMethods">
<aop:after method="postGreeting" pointcut-ref="greetToPointcut2"/>
</aop:aspect>
</aop:config>
三、各類加強類型的配置測試
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:after-returning method="afterReturning" pointcut="target(com.baobaotao.SmartSeller)" returning="retVal" /> </aop:aspect> </aop:config>
2)環繞加強spa
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:around method="aroundMethod" pointcut="execution(* serveTo(..)) and within(com.baobaotao.Waiter)" /> </aop:aspect> </aop:config>
3)拋出異常加強code
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:after-throwing method="afterThrowingMethod" pointcut="target(com.baobaotao.SmartSeller) and execution(* checkBill(..))" throwing="iae" /> </aop:aspect> </aop:config>
4)Final加強xml
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:after method="afterMethod" pointcut="execution(* com..*.Waiter.greetTo(..))" /> </aop:aspect> </aop:config>
5)引介加強
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:declare-parents implement-interface="com.baobaotao.Seller" default-impl="com.baobaotao.SmartSeller" types-matching="com.baobaotao.Waiter+" /> </aop:aspect> </aop:config>
<aop:config proxy-target-class="true"> <aop:aspect ref="adviceMethods"> <aop:before method="bindParams" pointcut="target(com.yyq.schema.NaiveWaiter) and args(name,num,..)"/> </aop:aspect> </aop:config>
AdviceMethods綁定參數的加強方法:
//------------綁定鏈接點參數----------// public void bindParams(int num,String name){ System.out.println("----bindParams()----"); System.out.println("name:"+name); System.out.println("num:"+num); System.out.println("----bindParams()----"); }
<aop:config proxy-target-class="true"> <aop:advisor advice-ref="testAdvice" pointcut="execution(* com..*.Waiter.greetTo(..))"/> </aop:config> <bean id="testAdvice" class="com.yyq.schema.TestBeforeAdvice"/>
加強類:
package com.yyq.schema; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class TestBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("------TestBeforeAdvice------"); System.out.println("clientName:"+args[0]); System.out.println("------TestBeforeAdvice------"); } }