使用pojo+xml開發aop

使用pojo+xml開發aop

基於xml的配置是spring專有的.aspectj得到越來越多的支持,具備更好的重用性.
我們可以在xml中配置通知的幾種情況,分別爲前置通知,後置通知,環繞通知,異常通知和引入通知。

1.首先創建一個類爲切面,類中實現的方法爲具體的通知,具體的實現爲實現的前置通知,後置通知,環繞通知,異常通知和引入通知。類名爲AdviceUtil.java,
package cn.csdn.hr.advice;
import org.aspectj.lang.ProceedingJoinPoint;
//切面
public class AdviceUtil {
	//前置通知
	public void getUp() {
		// TODO Auto-generated method stub
		System.out.println("老王起來啦!");
	}
}
2.然後我們要有業務邏輯,來測試
EmployeeService.java 接口
package cn.csdn.hr.service;
public interface EmployeeService {
	// 工作
	public void work();
}

實現的具體的類爲,EmployeeServiceBean.java:
package cn.csdn.hr.service;
public class EmployeeServiceBean implements EmployeeService {
	@Override
	public void work() {
		// TODO Auto-generated method stub
		System.out.println("開始工作l===================");
	}
}


3.在bean.xml中的配置,首先要引入aop,引入的格式爲:
xmlns:aop=http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
所以,在bean.xml中我們可以使用:
<aop:config></aop:config>標籤,這個標籤aop配置的聲明包括了通知和切面 
<aop:pointcut></aop:pointcut>標籤用來聲明切入點
<aop:aspect></aop:aspect>標籤用來配置切面
<aop:before/>帶有參數的前置通知
	<aop:around/>環繞通知 
<aop:after/>後置通知			
<aop:after-returning />
	<aop:after-throwing />
<aop:declare-parents/> 引用通知

對上面聲明的類的前置通知的使用代碼爲:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-2.5.xsd ">
<!—注入切面的bean -->
<bean id="adviceUtil" class="cn.csdn.hr.advice.AdviceUtil"></bean>
<!-- 聲明業務bean -->
<bean id="employeeServiceBean" class="cn.csdn.hr.service.EmployeeServiceBean"></bean>
<!-- aop配置的聲明  包括了通知和切面   -->
	<aop:config>	
		<!-- 聲明切入點 -->
		<aop:pointcut expression="execution(* cn.csdn.hr..*.*work(..))" id="myPointcut"/>
		<!-- 配置切面   order是優先級 -->
		<aop:aspect ref="adviceUtil">
			<!--配置前置通知        method是方法名-->
			<aop:before method="getUp" pointcut-ref="myPointcut"/>
		</aop:aspect>
	</aop:config>
</beans>

然後我們可以一次類推來配置後置通知,在AdviceUtil.java中加入方法爲:
//後置通知
	public void goHome() {
		System.out.println("回家吧!=================");
	}
在bean.xml中配置後置通知爲:
<!-- 後置通知 -->
<aop:after method="goHome" pointcut-ref="myPointcut"/>

環繞通知爲:
//環繞通知
	public Object punchCard(ProceedingJoinPoint jp) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("打卡前============!");
		Object obj = jp.proceed();
		System.out.println("打卡後============!");
		return obj;
	}

在AdviceUtil.java中的配置爲:
<!--環繞通知 -->
<aop:around method="punchCard" pointcut-ref="myPointcut"/>

後置通知之後的通知和異常通知爲:
	//後置通知之後的通知  after-returning
	public void back(Object ret){
		System.out.println("運行back方法================="+ret);
	}
	
	//異常處理通知
	public void unwell(Exception ex){
		System.out.println("不舒服====================="+ex.getMessage());
	}
在bean.xml中的配置爲:
<aop:after-returning method="back" pointcut-ref="myPointcut" returning="ret"/>
	<aop:after-throwing method="unwell" pointcut-ref="myPointcut" throwing="ex"/>

帶有參數的前置通知:
在AdviceUtil.java中添加一個方法:

	// 具體的實現爲通知
	public void checkLogin(String name, String pass) {
		System.out.println("檢查用戶的用戶名:" + name + ",密碼爲:" + pass);
	}

在bean.xml中的配置爲:
<aop:pointcut expression="execution(* cn.csdn.hr..*.*work(..)) and args(name,pass)" id="myPointcut1"/>
<!-- 帶有參數的前置通知-->
<aop:before method="checkLogin" pointcut-ref="myPointcut1"/>
同時還要在service中寫一個帶有兩個參數的方法纔可以,在EmployeeService.java中添加的方法爲:
public void work(String uname,String upass);

在EmployeeServiceBean.java中實現的方法爲:
@Override
	public void work(String uname, String upass) {
		// TODO Auto-generated method stub
	System.out.println(uname+"============="+upass+"==============");
	}

這樣,纔可以實現有參數的前置通知。



引用通知
我們以一個添加最後的時間爲例,首先寫出Auditable.java的接口來寫方法:
package cn.csdn.hr.advice;
import java.util.Date;
public interface Auditable {
	//引入  就是添加新的功能        修改日期的接口
	//添加屬性:記錄最後一次修改的時間
	void setLastModifiedDate(Date lastModifiefDate);
	Date getLastModifiedDate();
}

在AuditableAdvice.java中實現爲:
package cn.csdn.hr.advice;
import java.util.Date;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;

/*
 * 引入通知,繼承DelegatingIntroductionInterceptor接口,使用引入的攔截器
 */
@SuppressWarnings("serial")
public class AuditableAdvice extends DelegatingIntroductionInterceptor implements
		Auditable {

	private Date lastModifiedDate;
	
	//DefaultIntroductionAdvisor

	@Override
	public void setLastModifiedDate(Date lastModifiefDate) {
		// TODO Auto-generated method stub
		this.lastModifiedDate = lastModifiefDate;
	}
	@Override
	public Date getLastModifiedDate() {
		// TODO Auto-generated method stub
		System.out.println("最後一次修改的時間爲:"+lastModifiedDate);
		return lastModifiedDate;
	}
}

在AdviceUtil.java中沒有實現的方法,因爲在以上的接口和實現類中的已經實現,在bean.xml中的配置爲:
<aop:declare-parents types-matching="*..EmployeeServiceBean" implement-interface="cn.csdn.hr.advice.Auditable" default-impl="cn.csdn.hr.advice.AuditableAdvice"/>

測試的方法爲:
package cn.csdn.hr.junit;
import java.util.Date;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.csdn.hr.advice.Auditable;
import cn.csdn.hr.service.EmployeeService;
public class AppMain {
	@Test
	public void test() {
		ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");

		EmployeeService employeeService = (EmployeeService) ac
				.getBean("employeeServiceBean");

		employeeService.work();

		employeeService.work("老王", "222");
		
		Auditable auditable = (Auditable) employeeService;
		auditable.setLastModifiedDate(new Date());
		System.out.println(auditable.getLastModifiedDate());
	}
}

最後測試的結果爲:
老王 起來啦!
打卡前============!
開始工作l===================
打卡後============!
回家吧!=================
運行back方法=================null
老王 起來啦!
檢查用戶的用戶名:老王,密碼爲:222
打卡前============!
老王=============222==============
打卡後============!
回家吧!=================
運行back方法=================null
最後一次修改的時間爲:Thu Apr 19 09:15:49 GMT 2012
Thu Apr 19 09:15:49 GMT 2012





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章