Spring使您能够在xml文件中定义方面,建议和切入点。
在上一页中,我们已经看到了使用批注的aop示例。现在,我们将通过xml配置文件看到相同的示例。
让我们看看用于定义建议的xml元素。
aop: before
在调用实际的业务逻辑方法之前应用。
aop: after
在调用实际的业务逻辑方法之后应用。
aop: 返回后
在调用实际的业务逻辑方法后应用。可用于拦截通知中的返回值。
aop: around
在调用实际的业务逻辑方法之前和之后都将应用。
aop: 投掷后
如果实际的业务逻辑方法抛出异常,则将其应用。
在实际业务逻辑方法之前应用"先行AspectJ建议"。您可以在此处执行任何操作,例如转换,身份验证等。
创建一个包含实际业务逻辑的类。
文件: 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;} }
现在,创建包含在建议之前的方面类。
文件: 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()); } }
现在创建定义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()方法之前,还会打印出其他问题。
在调用实际的业务逻辑方法之后,应用了通知之后的AspectJ。它可用于维护日志,安全性,通知等。
在这里,我们假设
Operation.java
,
TrackOperation.java
和
Test.java
文件与aop: 中的示例相同。
现在创建定义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()方法之后,还会出现其他问题。
通过在返回建议后使用,我们可以在建议中获得结果。
创建
文件: 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;} }
创建返回建议后包含的方面类。
文件: 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
现在创建调用实际方法的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周围建议是在调用实际的业务逻辑方法之前和之后应用的。
创建一个类
文件: 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");} }
创建包含围绕建议的方面类。
您需要在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
现在创建调用实际方法的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建议的示例。
创建包含业务逻辑的类。
文件: 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");
}
}
}
创建引发建议后包含的方面类。
在这里,我们还需要传递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
现在创建调用实际方法的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