使用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
使用pojo+xml開發aop
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.