Spring的Aop的实现方式

本文通过一个具体的示例,介绍了Spring AOP的工作原理及其与Java动态代理的关系。通过对比不同实现方式,展示了如何利用Java动态代理简化重复代码,并最终实现Spring AOP的配置式事务管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看了一下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 None.gif 方法一。
 2 None.gif    更改seat()方法,在这个方法的第一句加上
 3 None.gif    System.out.println( " buy ticket  " );
 4 None.gif    最后一句加上
 5 None.gif    System.out.println( " check ticket  " );
 6 None.gif    然後调用
 7 None.gif    ByBus bb  =   new  ByBus();
 8 None.gif    bb.seat();
 9 None.gif    bb.rob();
10 None.gif方法二。
11 None.gif    再调用之前加上    
12 None.gif    ByBus bb  =   new  ByBus();
13 None.gif    System.out.println( " buy ticket  " );
14 None.gif    bb.seat();
15 None.gif    System.out.println( " check ticket  " );
16 None.gif    bb.seat();
17 None.gif方法三。
18 None.gif    利用代理模式,定义一个接口IByBus . ByBus实现接口 ,定义一个代理类,实现IByBus接口
19 ExpandedBlockStart.gifContractedBlock.gif     public   class  ProxyByBus  implements  IByBus dot.gif {
20InBlock.gif        private IByBus byBus;
21ExpandedSubBlockStart.gifContractedSubBlock.gif        public ProxyByBus(IByBus byBus)dot.gif{
22InBlock.gif            this.byBus = byBus;
23ExpandedSubBlockEnd.gif        }

24ExpandedSubBlockStart.gifContractedSubBlock.gif        public void seat()dot.gif{
25InBlock.gif            System.out.println("buy ticket ");
26InBlock.gif            byBus.seat();
27InBlock.gif            System.out.println("check ticket ");
28ExpandedSubBlockEnd.gif        }

29ExpandedSubBlockStart.gifContractedSubBlock.gif        public void rob()dot.gif{
30InBlock.gif            byBus.rob();
31ExpandedSubBlockEnd.gif        }

32ExpandedBlockEnd.gif    }

33 None.gif

以上三种方法都面临一个问题,如果函数很多,类也很多,以上几种方式的实现都不是很美观。那没有没有更好的
方式呢,这个时候Java的动态代理加入.能较好的解决这个问题,例如我们要加入一种旅游方式ByTrain
定义IByTrain接口,下边是利用动态代理的实现:
定义一个使用动态代理的类

 1 None.gif package  proxy;
 2 None.gif
 3 None.gif import  java.lang.reflect.InvocationHandler;
 4 None.gif import  java.lang.reflect.Method;
 5 None.gif import  java.lang.reflect.Proxy;
 6 None.gif
 7 ExpandedBlockStart.gifContractedBlock.gif public   class  TxHandler  implements  InvocationHandler dot.gif {
 8InBlock.gif    private Object originalObject;
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object bind(Object obj)dot.gif{
10InBlock.gif        this.originalObject = obj;
11InBlock.gif        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
12InBlock.gif                obj.getClass().getInterfaces(),this);
13ExpandedSubBlockEnd.gif    }

14InBlock.gif    //加入buy ticket ,check ticket
15ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable dot.gif{
16InBlock.gif        Object result = null;
17ExpandedSubBlockStart.gifContractedSubBlock.gif        if(method.getName().startsWith("seat"))dot.gif{
18InBlock.gif            System.out.println("buy ticket");
19InBlock.gif            result = method.invoke(originalObject, args);
20InBlock.gif            System.out.println("check ticket");
21ExpandedSubBlockStart.gifContractedSubBlock.gif        }
elsedot.gif{
22InBlock.gif            result = method.invoke(originalObject, args);
23ExpandedSubBlockEnd.gif        }

24InBlock.gif        return result;
25ExpandedSubBlockEnd.gif    }

26ExpandedBlockEnd.gif}

27 None.gif定义一个辅助类
28 None.gif package  proxy;
29 None.gif
30 ExpandedBlockStart.gifContractedBlock.gif public   class  Util  dot.gif {
31ExpandedSubBlockStart.gifContractedSubBlock.gif    public static Object getObject(String name)dot.gif{
32InBlock.gif        Object obj= null;
33ExpandedSubBlockStart.gifContractedSubBlock.gif        trydot.gif{
34InBlock.gif            Class clazz = Class.forName(name);
35InBlock.gif            obj = clazz.newInstance();
36InBlock.gif            
37InBlock.gif            TxHandler th = new TxHandler();
38InBlock.gif            obj = th.bind(obj);
39ExpandedSubBlockStart.gifContractedSubBlock.gif        }
catch(Exception e)dot.gif{
40ExpandedSubBlockEnd.gif        }

41InBlock.gif        return obj;
42ExpandedSubBlockEnd.gif    }

43ExpandedBlockEnd.gif}

44 None.gif
45 None.gif然後测试一下结果:
46 None.gif package  proxy;
47 None.gif import  java.lang.reflect.Method;
48 ExpandedBlockStart.gifContractedBlock.gif public   class  Test  dot.gif {
49ExpandedSubBlockStart.gifContractedSubBlock.gif    public static void main(String[] args) dot.gif{
50ExpandedSubBlockStart.gifContractedSubBlock.gif        trydot.gif{
51InBlock.gif            String name1 ="proxy.ByBusImpl";
52InBlock.gif            IByBus byBus = (IByBus)Util.getObject(name1);
53InBlock.gif            byBus.seat();
54InBlock.gif            byBus.rob();
55InBlock.gif            //加入一种旅游方式
56InBlock.gif            String name2 ="proxy.ByTrainImpl";
57InBlock.gif            IByTrain byTrain = (IByTrain)Util.getObject(name2);
58InBlock.gif            byTrain.seat();
59InBlock.gif            byTrain.rob();
60InBlock.gif            
61ExpandedSubBlockStart.gifContractedSubBlock.gif        }
catch(Exception e)dot.gif{
62InBlock.gif            e.printStackTrace();
63ExpandedSubBlockEnd.gif        }

64ExpandedSubBlockEnd.gif    }

65ExpandedBlockEnd.gif}

ok我们也实现了同样的效果,看看代码量比前几种的更多,但是试想一下如果我们的旅游方式变的越来越多,
ByAir By...等等是否这中方式更简单了呢。

理解了Java的动态代理,再回到Spring,
Spring的IOC就类似Util类的作用,根据配制文件(本例中的字符串),在运行时自动生成代理类。
Spring的Aop就类似TxHandler类的作用,须要的函数例如seat()之前,之后都加入一写东西,
Spring加入的是

 1 ExpandedBlockStart.gif ContractedBlock.gif      try dot.gif {
 2InBlock.gif        //之前加入(类似buy ticket)
 3InBlock.gif        Transation.begin();
 4InBlock.gif        
 5InBlock.gif        //调用你的函数dot.gifdot.gif.
 6InBlock.gif        
 7InBlock.gif        //之后加入(类似check ticket)
 8InBlock.gif        Transation.commit() 
 9ExpandedBlockStart.gifContractedBlock.gif    }
catch (Exception e) dot.gif {
10InBlock.gif        //加入
11InBlock.gif        Transation.rollback();
12ExpandedBlockEnd.gif    }

13 None.gif


这样你就能在配制文件中来管理事务了。
 
本文提供实例source下载,见这里:http://www.blogjava.net/Files/dreamstone/proxy.rar
参考文献:夏昕的SpringGuide

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值