Spring使您能夠在xml文件中定義方面,建議和切入點。
在上一頁中,我們已經看到了使用批注的aop示例?,F在,我們將通過xml配置文件看到相同的示例。
讓我們看看用于定義建議的xml元素。
aop: before
在調用實際的業(yè)務邏輯方法之前應用。
aop: after
在調用實際的業(yè)務邏輯方法之后應用。
aop: 返回后
在調用實際的業(yè)務邏輯方法后應用??捎糜跀r截通知中的返回值。
aop: around
在調用實際的業(yè)務邏輯方法之前和之后都將應用。
aop: 投擲后
如果實際的業(yè)務邏輯方法拋出異常,則將其應用。
在實際業(yè)務邏輯方法之前應用"先行AspectJ建議"。您可以在此處執(zhí)行任何操作,例如轉換,身份驗證等。
創(chuàng)建一個包含實際業(yè)務邏輯的類。
文件: Operation.javapackage com.nhooo; public class Operation{ public void msg(){System.out.println("msg method invoked");} public int m(){System.out.println("m method invoked");return 2;} public int k(){System.out.println("k method invoked");return 3;} }
現在,創(chuàng)建包含在建議之前的方面類。
文件: TrackOperation.java
package com.nhooo; import org.aspectj.lang.JoinPoint; public class TrackOperation{ public void myadvice(JoinPoint jp)//it is advice { System.out.println("additional concern"); //System.out.println("Method Signature: " + jp.getSignature()); } }
現在創(chuàng)建定義bean的applicationContext.xml文件。
文件: applicationContext.xml
<?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:aspectj-autoproxy /> <bean id="opBean" class="com.nhooo.Operation"> </bean> <bean id="trackAspect" class="com.nhooo.TrackOperation"></bean> <aop:config> <aop:aspect id="myaspect" ref="trackAspect" > <!-- @Before --> <aop:pointcut id="pointCutBefore" expression="execution(* com.nhooo.Operation.*(..))" /> <aop:before method="myadvice" pointcut-ref="pointCutBefore" /> </aop:aspect> </aop:config> </beans>
現在,讓我們稱為實際方法。
文件: Test.java
package com.nhooo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test{ public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Operation e = (Operation) context.getBean("opBean"); System.out.println("calling msg..."); e.msg(); System.out.println("calling m..."); e.m(); System.out.println("calling k..."); e.k(); } }
輸出
calling msg... additional concern msg() method invoked calling m... additional concern m() method invoked calling k... additional concern k() method invoked
如您所見,在調用msg(),m()和k()方法之前,還會打印出其他問題。
在調用實際的業(yè)務邏輯方法之后,應用了通知之后的AspectJ。它可用于維護日志,安全性,通知等。
在這里,我們假設
Operation.java
,
TrackOperation.java
和
Test.java
文件與aop: 中的示例相同。
現在創(chuàng)建定義bean的applicationContext.xml文件。
文件: applicationContext.xml
<?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:aspectj-autoproxy /> <bean id="opBean" class="com.nhooo.Operation"> </bean> <bean id="trackAspect" class="com.nhooo.TrackOperation"></bean> <aop:config> <aop:aspect id="myaspect" ref="trackAspect" > <!-- @After --> <aop:pointcut id="pointCutAfter" expression="execution(* com.nhooo.Operation.*(..))" /> <aop:after method="myadvice" pointcut-ref="pointCutAfter" /> </aop:aspect> </aop:config> </beans>
輸出
calling msg... msg() method invoked additional concern calling m... m() method invoked additional concern calling k... k() method invoked additional concern
您可以看到在調用msg(),m()和k()方法之后,還會出現其他問題。
通過在返回建議后使用,我們可以在建議中獲得結果。
創(chuàng)建
文件: Operation.java
package com.nhooo; public class Operation{ public int m(){System.out.println("m() method invoked");return 2;} public int k(){System.out.println("k() method invoked");return 3;} }
創(chuàng)建返回建議后包含的方面類。
文件: TrackOperation.java
package com.nhooo; import org.aspectj.lang.JoinPoint; public class TrackOperation{ public void myadvice(JoinPoint jp,Object result)//it is advice (after advice) { System.out.println("additional concern"); System.out.println("Method Signature: " + jp.getSignature()); System.out.println("Result in advice: "+result); System.out.println("end of after returning advice..."); } }
文件: applicationContext.xml
<?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:aspectj-autoproxy /> <bean id="opBean" class="com.nhooo.Operation"> </bean> <bean id="trackAspect" class="com.nhooo.TrackOperation"></bean> <aop:config> <aop:aspect id="myaspect" ref="trackAspect" > <!-- @AfterReturning --> <aop:pointcut id="pointCutAfterReturning" expression="execution(* com.nhooo.Operation.*(..))" /> <aop:after-returning method="myadvice" returning="result" pointcut-ref="pointCutAfterReturning" /> </aop:aspect> </aop:config> </beans>
文件: Test.java
現在創(chuàng)建調用實際方法的Test類。
package com.nhooo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test{ public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Operation e = (Operation) context.getBean("opBean"); System.out.println("calling m..."); System.out.println(e.m()); System.out.println("calling k..."); System.out.println(e.k()); } }
輸出
calling m... m() method invoked additional concern Method Signature: int com.nhooo.Operation.m() Result in advice: 2 end of after returning advice... 2 calling k... k() method invoked additional concern Method Signature: int com.nhooo.Operation.k() Result in advice: 3 end of after returning advice... 3
您可以看到返回值被打印兩次,一次是由TrackOperation類打印,第二次是Test類。
AspectJ周圍建議是在調用實際的業(yè)務邏輯方法之前和之后應用的。
創(chuàng)建一個類
文件: Operation.java
package com.nhooo; public class Operation{ public void msg(){System.out.println("msg() is invoked");} public void display(){System.out.println("display() is invoked");} }
創(chuàng)建包含圍繞建議的方面類。
您需要在advice方法中傳遞
PreceedingJoinPoint
引用,以便我們可以通過調用proceed來進行請求()方法。
文件: TrackOperation.java
package com.nhooo; import org.aspectj.lang.ProceedingJoinPoint; public class TrackOperation { public Object myadvice(ProceedingJoinPoint pjp) throws Throwable { System.out.println("Additional Concern Before calling actual method"); Object obj=pjp.proceed(); System.out.println("Additional Concern After calling actual method"); return obj; } }
文件: applicationContext.xml
<?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:aspectj-autoproxy /> <bean id="opBean" class="com.nhooo.Operation"> </bean> <bean id="trackAspect" class="com.nhooo.TrackOperation"></bean> <aop:config> <aop:aspect id="myaspect" ref="trackAspect" > <!-- @Around --> <aop:pointcut id="pointCutAround" expression="execution(* com.nhooo.Operation.*(..))" /> <aop:around method="myadvice" pointcut-ref="pointCutAround" /> </aop:aspect> </aop:config> </beans>
文件: Test.java
現在創(chuàng)建調用實際方法的Test類。
package com.nhooo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test{ public static void main(String[] args){ ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml"); Operation op = (Operation) context.getBean("opBean"); op.msg(); op.display(); } }
輸出
Additional Concern Before calling actual method msg() is invoked Additional Concern After calling actual method Additional Concern Before calling actual method display() is invoked Additional Concern After calling actual method
您可以看到在調用msg()和顯示方法之前和之后,還會打印出其他問題。
通過使用擲后建議,我們可以在TrackOperation類中打印異常。讓我們看一下AspectJ AfterThrowing建議的示例。
創(chuàng)建包含業(yè)務邏輯的類。
文件: Operation.java
package com.nhooo;
public class Operation{
public void validate(int age)throws Exception{
if(age<18){
throw new ArithmeticException("Not valid age");
}
else{
System.out.println("Thanks for vote");
}
}
}
創(chuàng)建引發(fā)建議后包含的方面類。
在這里,我們還需要傳遞Throwable引用,以便我們可以在此處攔截異常。
文件: TrackOperation.java
package com.nhooo; import org.aspectj.lang.JoinPoint; public class TrackOperation{ public void myadvice(JoinPoint jp,Throwable error)//it is advice { System.out.println("additional concern"); System.out.println("Method Signature: " + jp.getSignature()); System.out.println("Exception is: "+error); System.out.println("end of after throwing advice..."); } }
文件: applicationContext.xml
<?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:aspectj-autoproxy /> <bean id="opBean" class="com.nhooo.Operation"> </bean> <bean id="trackAspect" class="com.nhooo.TrackOperation"></bean> <aop:config> <aop:aspect id="myaspect" ref="trackAspect" > <!-- @AfterThrowing --> <aop:pointcut id="pointCutAfterThrowing" expression="execution(* com.nhooo.Operation.*(..))" /> <aop:after-throwing method="myadvice" throwing="error" pointcut-ref="pointCutAfterThrowing" /> </aop:aspect> </aop:config> </beans>
文件: Test.java
現在創(chuàng)建調用實際方法的Test類。
package com.nhooo; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test{ public static void main(String[] args){ ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Operation op = (Operation) context.getBean("opBean"); System.out.println("calling validate..."); try{ op.validate(19); }catch(Exception e){System.out.println(e);} System.out.println("calling validate again..."); try{ op.validate(11); }catch(Exception e){System.out.println(e);} } }
輸出
calling validate... Thanks for vote calling validate again... additional concern Method Signature: void com.nhooo.Operation.validate(int) Exception is: java.lang.ArithmeticException: Not valid age end of after throwing advice... java.lang.ArithmeticException: Not valid age