1. 程式人生 > >Spring AOP+AspectJ在XML配置例項(詳解)

Spring AOP+AspectJ在XML配置例項(詳解)

在本教程中,我們將向你展示如何轉換上章節中 轉成基於XML的配置。對於那些不喜歡註釋,使用JDK1.4,則可以基於XML,而不使用 AspectJ。再次回顧上個 customerBo 介面中的幾個方法,以後你將學會如何在 XML檔案實現 AspectJ 攔截。

File:CustomerBo.java

public interface CustomerBo {

	void addCustomer();
	
	String addCustomerReturnValue();
	
	void addCustomerThrowException() throws Exception;
	
	void addCustomerAround(String name);
}

File:CustomerBoImpl.java

public class CustomerBoImpl implements CustomerBo{

	@Override
	public void addCustomer() {
		System.out.println("addCustomer() is running");
	}

	@Override
	public String addCustomerReturnValue() {
		System.out.println("addCustomerReturnValue() is running");
		return "abc";
	}

	@Override
	public void addCustomerThrowException() throws Exception {
		System.out.println("addCustomerThrowException() is running");
		throw new Exception("Error");
	}

	@Override
	public void addCustomerAround(String name) {
		System.out.println("addCustomerAround() is running, args: " + name);
	}

}

1. AspectJ <aop:before> = @Before

File:LoggingAspect.java

public class LoggingAspect {

	public void logBefore() {
		System.out.println("logBefore() is running!");
		System.out.println("******");
	}
}

File:applicationContext.xml

在XML同等功能,使用 <aop:before>.

<?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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLogging" ref="logAspect">
			<!-- @Before -->
			<aop:pointcut expression="execution(* com.ray.customer.bo.CustomerBo.addCustomer(..))" id="pointCutBefore"/>
			<aop:before method="logBefore" pointcut-ref="pointCutBefore"/>
		</aop:aspect>
	</aop:config>
</beans>

執行程式

public class Test {

	public static void main(String[] args) throws Exception {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerBo customer = (CustomerBo) context.getBean("customerBo");
		customer.addCustomer();
	}
}

執行結果

logBefore() is running!
******
addCustomer() is running

2. AspectJ <aop:after> = @After

File:LoggingAspect.java

public class LoggingAspect {

	public void logAfter() {
		System.out.println("logAfter() is running!");
		System.out.println("******");
	}
}

File:applicationContext.xml

在XML同等功能,使用 <aop:after>實現。

<?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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLogging" ref="logAspect">
			<!-- @After -->
			<aop:pointcut expression="execution(* com.ray.customer.bo.CustomerBo.addCustomer(..))" id="pointCutAfter"/>
			<aop:after method="logAfter" pointcut-ref="pointCutAfter"/>
		</aop:aspect>
	</aop:config>
</beans>

執行結果

addCustomer() is running
logAfter() is running!
******

3. AspectJ <aop:after-returning> = @AfterReturning

File:LoggingAspect.java

public class LoggingAspect {

	public void logAfterReturning(JoinPoint jp,Object result) {
		System.out.println();
		System.out.println("logAfterReturning() is running!");
		System.out.println("getName(): " + jp.getSignature().getName());
		System.out.println("Method returned value is : " + result);
		System.out.println("******");
	}
}

File:applicationContext.xml

在XML同等功能 - 使用 <aop:after-returning>.

<?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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLogging" ref="logAspect">
			<!-- @AfterReturning -->
			<aop:pointcut expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerReturnValue(..))" id="pointCutAfterReturning"/>
			<aop:after-returning method="logAfterReturning" pointcut-ref="pointCutAfterReturning" returning="result"/>
		</aop:aspect>
	</aop:config>
</beans>

執行程式

public class Test {

	public static void main(String[] args) throws Exception {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerBo customer = (CustomerBo) context.getBean("customerBo");
		customer.addCustomerReturnValue();
	}
}

執行結果

addCustomerReturnValue() is running

logAfterReturning() is running!
getName(): addCustomerReturnValue
Method returned value is : abc
******

4. AspectJ <aop:after-throwing> = @AfterThrowing

File:LoggingAspect.java

public class LoggingAspect {

	public void logAfterThrowing(JoinPoint jp,Throwable error) {
		System.out.println();
		System.out.println("logAfterThrowing() is running!");
		System.out.println("getName() : " + jp.getSignature().getName());
		System.out.println("Exception : " + error);
		System.out.println("******");
	}
}

File:applicationContext.xml

在XML同等功能 - 使用 <aop:after-throwing>.

<?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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLogging" ref="logAspect">
			<!-- @AfterThrowing -->
			<aop:pointcut expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerThrowException(..))" id="pointCutAfterThrowing"/>
			<aop:after-throwing method="logAfterThrowing" pointcut-ref="pointCutAfterThrowing" throwing="error"/>
		</aop:aspect>
	</aop:config>
</beans>

執行程式

public class Test {

	public static void main(String[] args) throws Exception {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerBo customer = (CustomerBo) context.getBean("customerBo");
		customer.addCustomerThrowException();
	}
}

執行結果

addCustomerThrowException() is running

logAfterThrowing() is running!
getName() : addCustomerThrowException
Exception : java.lang.Exception: Error
******
Exception in thread "main" java.lang.Exception: Error
	at com.ray.customer.bo.impl.CustomerBoImpl.addCustomerThrowException(CustomerBoImpl.java:21)

5. AspectJ <aop:after-around> = @Around

File:LoggingAspect.java

public class LoggingAspect {

	public void logAround(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("logAround() is running!");
		System.out.println("getName(): " + pjp.getSignature().getName());
		
		System.out.println("before is running!");
		pjp.proceed();
		System.out.println("after is running!");
		System.out.println("******");
	}
}

File:applicationContext.xml

在XML同等功能 - 使用 <aop:after-around>.

<?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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLogging" ref="logAspect">
			<!-- @Around -->
			<aop:pointcut expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerAround(..))" id="pointCutAround"/>
			<aop:around method="logAround" pointcut-ref="pointCutAround"/>
		</aop:aspect>
	</aop:config>
</beans>

執行程式

public class Test {

	public static void main(String[] args) throws Exception {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerBo customer = (CustomerBo) context.getBean("customerBo");
		customer.addCustomerAround("ray");
	}
}

執行結果

logAround() is running!
getName(): addCustomerAround
before is running!
addCustomerAround() is running, args: ray
after is running!
******

完整的 XML 例項

File:LoggingAspect.java

package com.ray.aspect;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoggingAspect {

	public void logBefore(JoinPoint joinPoint) {

		System.out.println("logBefore() is running!");
		System.out.println("getName() : " + joinPoint.getSignature().getName());
		System.out.println("******");
	}

	public void logAfter(JoinPoint joinPoint) {

		System.out.println("logAfter() is running!");
		System.out.println("getName() : " + joinPoint.getSignature().getName());
		System.out.println("******");

	}
	
	public void logAfterReturning(JoinPoint joinPoint, Object result) {

		System.out.println("logAfterReturning() is running!");
		System.out.println("getName() : " + joinPoint.getSignature().getName());
		System.out.println("Method returned value is : " + result);
		System.out.println("******");

	}
	
	public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {

		System.out.println("logAfterThrowing() is running!");
		System.out.println("getName() : " + joinPoint.getSignature().getName());
		System.out.println("Exception : " + error);
		System.out.println("******");

	}
	
	public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

		System.out.println("logAround() is running!");
		System.out.println("getName() : " + joinPoint.getSignature().getName());
		System.out.println("getArgs() : " + Arrays.toString(joinPoint.getArgs()));
		
		System.out.println("Around before is running!");
		joinPoint.proceed();
		System.out.println("Around after is running!");
		
		System.out.println("******");

	}
	
}

File: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.xsd
	http://www.springframework.org/schema/aop
	http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<aop:aspectj-autoproxy/>
	
	<bean id="customerBo" class="com.ray.customer.bo.impl.CustomerBoImpl"/>
	
	<!-- Aspect -->
	<bean id="logAspect" class="com.ray.aspect.LoggingAspect"/>
	
	<aop:config>
		<aop:aspect id="aspectLoggging" ref="logAspect" >

			<!-- @Before -->
			<aop:pointcut id="pointCutBefore"
				expression="execution(* com.ray.customer.bo.CustomerBo.addCustomer(..))" />

			<aop:before method="logBefore" pointcut-ref="pointCutBefore" />
			
			<!-- @After -->
			<aop:pointcut id="pointCutAfter"
				expression="execution(* com.ray.customer.bo.CustomerBo.addCustomer(..))" />

			<aop:after method="logAfter" pointcut-ref="pointCutAfter" />
			
			<!-- @AfterReturning -->
			<aop:pointcut id="pointCutAfterReturning"
				expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerReturnValue(..))" />

			<aop:after-returning method="logAfterReturning" returning="result" 
				pointcut-ref="pointCutAfterReturning" />
			
			
			<!-- @AfterThrowing -->
			<aop:pointcut id="pointCutAfterThrowing"
				expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerThrowException(..))" />
			
			<aop:after-throwing method="logAfterThrowing" throwing="error" 
				pointcut-ref="pointCutAfterThrowing"  />
			
			
			<!-- @Around -->
			<aop:pointcut id="pointCutAround"
				expression="execution(* com.ray.customer.bo.CustomerBo.addCustomerAround(..))" />
			<aop:around method="logAround" pointcut-ref="pointCutAround"  />
		</aop:aspect>

	</aop:config>
</beans>

測試程式

package com.ray.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ray.customer.bo.CustomerBo;

public class Test {

	public static void main(String[] args) throws Exception {

		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		CustomerBo customer = (CustomerBo) context.getBean("customerBo");

//		customer.addCustomer();

//		customer.addCustomerReturnValue();

//		customer.addCustomerThrowException();

		customer.addCustomerAround("ray");
	}
}