最近看了一下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接口,下边是利用动态代理的实现:
定义一个使用动态代理的类
1package proxy;
2
3import java.lang.reflect.InvocationHandler;
4import java.lang.reflect.Method;
5import java.lang.reflect.Proxy;
6
7public 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定义一个辅助类
28package proxy;
29
30public 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然後测试一下结果:
46package proxy;
47import java.lang.reflect.Method;
48public 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://www.blogjava.net/Files/dreamstone/proxy.rar
参考文献:夏昕的SpringGuide