Spring AOP实践(一)动态代理和静态代理,为什么使用AOP

作为Spring仅次于IOC的第二大代表功能,AOP的应用就不是很广泛了。众所周知AOP是面向方面编程,是对面向对象编程做出补充的一种编程方式。AOP使得编程人员可以把分散在代码各个地方的相同功能抽象到一处进行处理。任何方法的出现都是因为有着广泛的需求,比如在编程的过程中你总会想:凡是遇到某某情况,就做某某事。这就是AOP所要解决的问题,凡是遇到某某情况,这里的某某情况就是切入点,而“就做某某事”中的某某事就是AOP所说的advice。

AOP解决的问题往往可以用代理模式来解决。java开发中常说动态代理和静态代理,而AOP就是动态代理,因为代理的类是在运行时才生成的。相反的所谓静态代理就是说代理在编译期就已经生成。

静态代理就是所谓的代理模式,如果去实现代理模式?假设我现在有一个类,我想要在这个类中每个public方法真正执行数据库操作前先查询缓存,这时候除了修改原始的类之外的方式就是我可以写个代理类来替代它,这样符合开闭原理。代理的意义就在于,在访问真实的数据前我必须先访问它的代理,那么在客户端代码看来代理和实际的类应该没有分别---他们需要是同一类型。要做到是同一类型有两种方式,第一是代理类作为原类的子类,通过继承并重写父类的方法来达到目的;第二种方法是继承同一接口,然后把原类作为成员变量组合进来。当然你也可以不用上面的两种方式,而是用一个类来组合原类,但是不实现同一接口,这样显然不好。最好的方式应该是实现同一接口,这就是接口的意义,接口的意义在于抽象,面向接口编程就是面向抽象编程。如果你的类有非static的public的方法,都应该考虑让他实现一个接口,很多时候我们会觉得给一个DAO或者service类多创建个interface是多余的,但是有朝一日你想到给他一个代理这样的需求的时候,你会发现如果他有个接口就完美了。

动态代理在于运行是生成java字节码,java的标准库有Proxy类,除此之外常常用到的就是cglib,cglib是个java字节码动态生成的解决方案。Spring AOP用到了cglib。cglib的使用需要定义方法拦截器,定义何时拦截哪个方法并做什么事。

使用动态代理还是静态代理?应该如果做出选择还是要看具体的情况。静态代理的性能肯定优于动态代理,动态代理因为使用到反射,需要在执行方法之前生成代码所以有一定的性能损失,但是这个损失大多数时候应该不大。使用动态代理还有个问题就是不好调试代码。比如使用Spring的AOP,有些时候你可能都不知道到底拦截成功了没,比如你在一个方法是使用@Transactional,即使这个注解是无效的Spring也不会给你报错。静态代理还可以使得代码的结构更加完整清晰,更加的面向对象。使用动态代理总有它的好处,那就是make life easy。如果我说一句凡是遇到下雨天就发封邮件给我,那么所有的工人都知道这么做就很好,我不需要给每个工人都说

if(it's rainning) {sending email to boss;}
这里的工人就是method。AOP就是这样的方式,我这需要在这里设定拦截的情况和该干什么就可以了。
阅读更多

没有更多推荐了,返回首页