一、一个简单切面的配置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------"); } }