以前有做过一次share,关于动态代理的,因为相关的应用遍及所用的Spring,Hibernate,Junit以及项目中通用的横切功能。看了<Expert one on one J2EE Development without EJB>,这里关于AOP的介绍,有了更全的实现策略,所以摘下来。
1. J2SE动态代理
在JAVA中,实现AOP最显而易见的策略莫过于使用JAVA1.3后引入的动态代理。它使我们可以为一个或多个接口“凭空”地创建实现对象,而不需要预先有一个实现类。如果需要用动态代理实现环绕增强,可以在其中调用必要的拦截器链。拦截器链上的最后一个拦截器将借助反射调用目标对象-如果有目标对象的话。
动态代理最大的好处在于:这时一种标准的JAVA语言特性。最大的局限是:它只能针对接口进行代理,不能针对类。一般情况下,这并不是坏事,因为AOP主要针对业务对象,而业务对象通常应该是放在业务接口之后的。
在针对接口进行代理时,Spring默认地使用动态代理。
2.动态字节码生成
为了针对JAVA类提供代理,我们需要动态代理之外的工具,这就是动态字节码生成。而JAVA的反射与类加载机制都非常开放,因此实现动态字节码生成库并不复杂。其中流行的就有CGLIB(code generation library).在Spring中,如果需要针对类(而不是接口)提供代理,就会用到CGLIB.它可以针对指定的类动态生成一个子类,并覆盖其中的方法,从而实现方法拦截。CGLIB风格的字节码增强被应用在Hibernate2.x版本中,并被证明是一种成熟的技术。不过CGLIB有一个小问题:因为它是通过继承来实现代理的,所以无法为final方法提供代理。
3.JAVA代码生成
也可以生成新的JAVA源码,在其中执行横切性的代码,就像EJB的代码生成策略一样。由于动态待俩和动态字节码生成技术的出现,这种做法正在逐渐退出流行。
4.使用定制的类加载器
如果我们希望对某个类的所有实例进行增强,应该怎么做?或者换个说法,如果我们希望确保某个类的所有实例都被增强过,应该如何去创建这些实例?答案是,我们可以改变new操作符的行为。在这种情况下,可以考虑利用JAVA类加载机制的可扩展性。通过定制一个自制的类加载器,我们可以在一个类被加载时自动对其进行增强。即使用户直接使用用new操作符构造实例,增强仍然会生效。Jboss和AspectWerks都采用这种做法对java类进行增强,具体的增强信息则是在运行时从XML配置文件中读取。这种做法的风险在于:它偏离了java的标准,在某些应用服务器中,这种做法可能会导致问题,因为J2EE服务器需要控制整个类加载的层次体系。
5.语言扩展
如果我们希望把方面当作一等公民来看,就需要一种同时支持AOP和OOP的语言。为了达到这个目的,可以对现有的OO语言进行扩展,AspectJ就对java进行了这样的扩展。