Spring的AOP實現之一 --- 用spring編寫Spring通知

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中的異常用



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