Spring的AOP實現之一 --- 用spring編寫Spring通知
創建通知是實現spring的面向切面的關鍵點之一
創建通知分爲環繞通知,前置通知,後置通知,異常通知,我們來一一介紹
1. Spring都是在service中實現的,爲了方便,我們來創建serviceImpl和service
(1)PersonService.java 接口
package cn.csdn.hr.service;
import java.util.Date;
public interface PersonService {
//學習科目和開始的日期
public void study(String name,Date startTime);
}
(2) PersonServiceBean.java 實現類
package cn.csdn.hr.service;
import java.util.Date;
public class PersonServiceBean implements PersonService {
@Override
public void study(String name, Date startTime) {
System.out.println("學習的科目爲:"+name+"學習的時間爲:+"+startTime);
}
2.創建bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">
</beans>
3.首先來寫環繞通知
環繞通知需要繼承MethodInterceptor接口並實現接口中的類
package cn.csdn.hr.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAroundAdvice implements MethodInterceptor{
//創建自己環繞的通知
@Override
public Object invoke(MethodInvocation methodInvoaction) throws Throwable {
System.out.println("執行方法之前執行操作");
//執行目標方法
Object object = methodInvoaction.proceed();
System.out.println("執行方法之後執行操作");
return object;
}
}
4.我們要在bean.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<!-- 配置環繞通知 -->
<bean id="myAroundAdvice" class="cn.csdn.hr.advice.MyAroundAdvice"/>
<!-- 業務bean -->
<bean id="personServiceBean" class="cn.csdn.hr.service.PersonServiceBean"></bean>
<!--代理的bean -->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 代理的接口 -->
<property name="proxyInterfaces">
<list>
<value>cn.csdn.hr.service.PersonService</value>
</list>
</property>
<!-- 攔截的名稱(通知的名稱)-->
<property name="interceptorNames">
<list>
<value>myAroundAdvice</value>
</list>
</property>
<!-- 執行的目標對象 即爲通知的對象-->
<property name="target">
<ref bean="personServiceBean"/>
</property>
</bean>
</beans>
注:需要注意的是我們要實現一個bean,class爲"org.springframework.aop.framework.ProxyFactoryBean"的類做代理的baen來和通知相關聯,在屬性名爲interceptorNames的value中配置指定的通知類的id名,
5.我們來測試一下吧!
public void test() {
// 獲取應用程序上下文對象
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
PersonService personService = (PersonService) ac.getBean("proxyFactoryBean");
personService.study("java", new Date());
}
測試結果爲:
執行方法之前執行操作
學習的科目爲:java學習的時間爲:+Wed Apr 18 08:30:13 GMT 2012
執行方法之後執行操作
一個通知寫完之後,剩下的通知也就好說了吧!但需要注入他們繼承的接口
1. 前置通知代碼 MyBeforeAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice{
/**
* 第一個參數:方法對象
* 第二個參數:方法參數
* 第三個對象:目標對象
*/
@Override
public void before(Method method, Object[] args, Object target)
throws Throwable {
Object obj=null;
if(args.length>0){
obj=args[0];
}
System.out.println("-----------before-------方法名稱:"+method.getName()+"-----第一個參數值----------:"+obj.toString()+"-------目標對象--------:"+obj.getClass());
}
}
在bean.xml中的配置爲:
<!-- 配置前置通知 -->
<bean id="myBeforeAdvice" class="cn.csdn.hr.advice.MyBeforeAdvice"/>
和
<value>myBeforeAdvice</value>
測試類和以上的一樣,測試的結果爲:
-----------before-------方法名稱:study-----第一個參數值----------:java-------目標對象--------:class java.lang.String
學習的科目爲:java學習的時間爲:+Wed Apr 18 09:24:47 GMT 2012
2.後置通知 MyAfterAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class MyAfterAdvice implements AfterReturningAdvice{
@Override
public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {
// 執行目標方法之後執行操作對象
System.out.println("==========after========方法的返回值:"+returnValue);
}
}
在bean.xml中的配置爲:
<!-- 配置後置通知 -->
<bean id="myAfterAdvice" class="cn.csdn.hr.advice.MyAfterAdvice" />
和<value>myAfterAdvice</value>
測試類和以上的一樣,測試的結果爲:
學習的科目爲:java學習的時間爲:+Wed Apr 18 09:26:19 GMT 2012
==========after========方法的返回值:null
3.異常通知 MyThrowsAdvice.java
package cn.csdn.hr.advice;
import java.lang.reflect.Method;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice{
public void afterThrowing(Method method, Object[] args,Object target,Throwable throwable){
System.out.println("異常的信息:"+throwable.getMessage());
}
}
在bean.xml中的配置
<!-- 配置異常通知 -->
<bean id="myThrowsAdvice" class="cn.csdn.hr.advice.MyThrowsAdvice" />
和
<value>myThrowsAdvice</value>
我們爲了測試,可以在PersonServiceBean中寫一個異常,爲:
Int i = 1/0;
當執行的時候結果爲:
學習的科目爲:java學習的時間爲:+Wed Apr 18 09:28:44 GMT 2012
異常的信息:/ by zero
如果在PersonServiceBean中的異常用
Spring的AOP實現之一 --- 用spring編寫Spring通知
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.