Spring AOP AspectJ Xml配置示例

Spring使您能够在xml文件中定义方面,建议和切入点。

在上一页中,我们已经看到了使用批注的aop示例。现在,我们将通过xml配置文件看到相同的示例。

让我们看看用于定义建议的xml元素。

aop: before 在调用实际的业务逻辑方法之前应用。 aop: after 在调用实际的业务逻辑方法之后应用。 aop: 返回后在调用实际的业务逻辑方法后应用。可用于拦截通知中的返回值。 aop: around 在调用实际的业务逻辑方法之前和之后都将应用。 aop: 投掷后如果实际的业务逻辑方法抛出异常,则将其应用。
注意: 要了解aop概念及其优势等,请访问此处。AOP概念教程

1、aop: before

在实际业务逻辑方法之前应用"先行AspectJ建议"。您可以在此处执行任何操作,例如转换,身份验证等。

创建一个包含实际业务逻辑的类。

文件: Operation.java
package 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()方法之前,还会打印出其他问题。


2、aop: 之后的示例

在调用实际的业务逻辑方法之后,应用了通知之后的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()方法之后,还会出现其他问题。


3、aop: 返回后的示例

通过在返回建议后使用,我们可以在建议中获得结果。

创建

文件: 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类。


4、aop: around

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()和显示方法之前和之后,还会打印出其他问题。


5、aop: after-throwing

通过使用掷后建议,我们可以在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