最近看了一下Spring的Aop和Java的動態代理,下邊利用個小例子,簡單的表述一下。
Spring中的Aop實現
一,什么是Aop呢:
AOP是Aspect Oriented Programming的縮寫,意思是面向方面編程。AOP實際是GoF設計模式的延續,
設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。
二,Spring中的Aop
spring中的aop運用了java中的動態代理來實現的,下邊是我寫的個小例子,便于理解,如有問題請提出。
1,需求:
我們經常遇到這樣的情況,在很多不同的操做開始和結尾要做相同的操做。舉個例子,比如你要實現一個對象
ByBus(乘坐公共汽車旅游)這個對象有一個seat()函數和一個rob()函數.如果你要正常乘車,在上車seat()之前
須要買票,在下車之前須要查票。如果你要做霸王車rob(),可以不用買票,也不用查票。
這個時候我們可以有以下兩種實現方法。
1
方法一。
2
更改seat()方法,在這個方法的第一句加上
3
System.out.println("buy ticket ");
4
最后一句加上
5
System.out.println("check ticket ");
6
然後調用
7
ByBus bb = new ByBus();
8
bb.seat();
9
bb.rob();
10
方法二。
11
再調用之前加上
12
ByBus bb = new ByBus();
13
System.out.println("buy ticket ");
14
bb.seat();
15
System.out.println("check ticket ");
16
bb.seat();
17
方法三。
18
利用代理模式,定義一個接口IByBus . ByBus實現接口 ,定義一個代理類,實現IByBus接口
19
public class ProxyByBus implements IByBus
{
20
private IByBus byBus;
21
public ProxyByBus(IByBus byBus)
{
22
this.byBus = byBus;
23
}
24
public void seat()
{
25
System.out.println("buy ticket ");
26
byBus.seat();
27
System.out.println("check ticket ");
28
}
29
public void rob()
{
30
byBus.rob();
31
}
32
}
33
以上三種方法都面臨一個問題,如果函數很多,類也很多,以上幾種方式的實現都不是很美觀。那沒有沒有更好的
方式呢,這個時候Java的動態代理加入.能較好的解決這個問題,例如我們要加入一種旅游方式ByTrain
定義IByTrain接口,下邊是利用動態代理的實現:
定義一個使用動態代理的類
1
package proxy;
2
3
import java.lang.reflect.InvocationHandler;
4
import java.lang.reflect.Method;
5
import java.lang.reflect.Proxy;
6
7
public class TxHandler implements InvocationHandler
{
8
private Object originalObject;
9
public Object bind(Object obj)
{
10
this.originalObject = obj;
11
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
12
obj.getClass().getInterfaces(),this);
13
}
14
//加入buy ticket ,check ticket
15
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
16
Object result = null;
17
if(method.getName().startsWith("seat"))
{
18
System.out.println("buy ticket");
19
result = method.invoke(originalObject, args);
20
System.out.println("check ticket");
21
}else
{
22
result = method.invoke(originalObject, args);
23
}
24
return result;
25
}
26
}
27
定義一個輔助類
28
package proxy;
29
30
public class Util
{
31
public static Object getObject(String name)
{
32
Object obj= null;
33
try
{
34
Class clazz = Class.forName(name);
35
obj = clazz.newInstance();
36
37
TxHandler th = new TxHandler();
38
obj = th.bind(obj);
39
}catch(Exception e)
{
40
}
41
return obj;
42
}
43
}
44
45
然後測試一下結果:
46
package proxy;
47
import java.lang.reflect.Method;
48
public class Test
{
49
public static void main(String[] args)
{
50
try
{
51
String name1 ="proxy.ByBusImpl";
52
IByBus byBus = (IByBus)Util.getObject(name1);
53
byBus.seat();
54
byBus.rob();
55
//加入一種旅游方式
56
String name2 ="proxy.ByTrainImpl";
57
IByTrain byTrain = (IByTrain)Util.getObject(name2);
58
byTrain.seat();
59
byTrain.rob();
60
61
}catch(Exception e)
{
62
e.printStackTrace();
63
}
64
}
65
}
ok我們也實現了同樣的效果,看看代碼量比前幾種的更多,但是試想一下如果我們的旅游方式變的越來越多,
ByAir By...等等是否這中方式更簡單了呢。
理解了Java的動態代理,再回到Spring,
Spring的IOC就類似Util類的作用,根據配制文件(本例中的字符串),在運行時自動生成代理類。
Spring的Aop就類似TxHandler類的作用,須要的函數例如seat()之前,之后都加入一寫東西,
Spring加入的是
1
try
{
2
//之前加入(類似buy ticket)
3
Transation.begin();
4
5
//調用你的函數
.
6
7
//之后加入(類似check ticket)
8
Transation.commit()
9
}catch(Exception e)
{
10
//加入
11
Transation.rollback();
12
}
13
這樣你就能在配制文件中來管理事務了。
本文提供實例source下載,見這里:http://m.tkk7.com/Files/dreamstone/proxy.rar
參考文獻:夏昕的SpringGuide