CgLib ,NCgLib 和AOP (之一)

CgLib ,NCgLib 和AOP

    广大关心编程前沿的程序员已经对AOP的感念耳熟能详了。无论是基于.NET的实现还是基于Java的实现都有很多开源的项目可供参考。
    对AOP不了解的读者可以到我得AOP专栏,熟悉一下AOP的基本概念。
    回顾AOP的历史可以看出,AOP并不是最近几年才冒出的“新”概念,据说历史可以追溯到施乐公司的一个实验室的项目。   
    从汇编语言,面向过程的编程,在到现在被广泛接受的OOP的编程思想,人们逐步抽象出对现实世界的描述。这每一步的进步,都使得我们对大规模的软件编程更容易控制和实现。
    那么为什么到了现在AOP才受到业界广泛关注呢?
    一方面OOP的编程思想相对成熟,也逐步显露出了其不能有效解决的领域,这部分需要新的思想来填充。另一方面就是程序语言的进步。
    大家知道AOP的特点之一是Interception,就是拦截。比如在方法执行前,执行中,执行后动态插入一些额外的方法,典型的就是日志,权限和事务控制。
    在基于虚拟机java 和 CLR 的.net 出现以前实现方法拦截,几乎不可能。 单单从Interception上说,珊瑚虫  和 木子版本的 QQ 就是一个 具有AOP特性的实现。大家有兴趣可以了解一下 珊瑚虫 或者 木子 版本的QQ的实现方式,可以说是呕心沥血,经历了无数次的重新启动和汇编测试,才实现了对QQ相关方法的拦截。
    因为无论是java的字节代码,还是.net的伪编译,他们生成的都不是最终的机器代码,而是平台无关的代码,这些代码在具体执行的时候还需要翻译成机器代码才可以执行。中间语言的出现使我们对执行前的代码有了更多的控制。
    正因为如此AOP的理论有了实现的可能,这个时候出现可谓水到渠成。
    一般来讲AOP的实现有3种途径:
    1 在编译成中间代码前就让代码具有AOP的特性,比如AspectWikez;
    2 使用语言特性,从设计方法出发,实现AOP,比如基于Java 的动态代理实现AOP。(见我得南宁系列文章);
    3 在中间代码运行时,动态修改中间代码,使其具有AOP特性。
    上面3种方法的有缺点我认为有几下几点:
    采用的一种方法,一般需要编译器的扩充支持,如同C编译器的出现代替汇编一样,需要长时间的验证其稳定性和效率。另外对于最终开发人员来说也需要学习这些编译器,或者新的语法指令完成这些功能,当然功能也最强大。
    第2种方法,我认为是一种轻量级别的实现,比如Nanning 和 DynAOP 等,一般这样的实现需要在设计上下功夫。比如需要基于接口编程。对于已有的项目来说,改动量非常大。
    第3种方法,介于1,2种方法之间。采用第3种方法实现AOP,不需要每个类都有一个接口,也没有什么编译器的更改。他的缺点是需要高超的编程技巧。正因为如此,才有很多项目用第3种方法包装后,给最终开发人员使用比如:Spring。
    实际上Spring 的AOP实现种第1,2种方法都采用了。
    我认为目前的项目种,大规模的采用AOP还不适合,一方面AOP还在发展之中,另一方面支持AOP的框架还没有被广泛的接受。
    正因为如此我们不妨直接操作中间代码,在项目的一些关键地方实现一些AOP的特性。
    那在Java的世界中可以用cglib,Javassist 等
    在.net的世界中可以用ncglib。
    下文我们来给出一些代码例子。
    (待续)

 

参考文章:
也谈判断一个程序是Debug 还是 Release
A Primer for Aspect-Oriented Programming in Java
反射发送实战(-)InvokeMember
http://aspectsharp.sourceforge.net/

通过Emit实现动态类生成

.NET WS客户端与Axis服务端的互操作问题

Nucleus.MockAOP.Net:OpenSource .Net AOP FrameWork

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
CGLIB(Code Generation Library)是一个强大的代码生成库,它可以在运行时动态生成字节码并生成新的类。在AOP(面向切面编程)中,CGLIB可以通过动态代理技术实现方法拦截和增强。 下面是使用CGLIB代理实现AOP的步骤: 1. 定义切面类 切面类是用于实现AOP功能的类,它包括切点(Pointcut)和通知(Advice)两个部分。切点是一组匹配连接点(Joinpoint)的规则,连接点可以是方法调用、方法入口、方法出口等。通知是在连接点上执行的操作,包括前置通知(Before)、后置通知(After)、返回通知(AfterReturning)、异常通知(AfterThrowing)和环绕通知(Around)。 2. 定义目标类 目标类是需要被代理的类,它包含需要被增强的方法。 3. 创建代理对象 使用CGLIB动态生成代理类,并创建代理对象。在创建代理对象时,需要传入切面类和目标类的实例。 4. 调用代理对象的方法 代理对象的方法调用会触发切面类中定义的通知方法,在通知方法中可以实现方法拦截和增强。 代码示例: 定义切面类: ``` public class LogAspect { public void before() { System.out.println("方法执行前"); } public void after() { System.out.println("方法执行后"); } } ``` 定义目标类: ``` public class UserService { public void addUser() { System.out.println("添加用户"); } } ``` 创建代理对象: ``` public class ProxyFactory implements MethodInterceptor { private Object target; public ProxyFactory(Object target) { this.target = target; } public Object getProxyInstance() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { LogAspect aspect = new LogAspect(); aspect.before(); Object result = method.invoke(target, args); aspect.after(); return result; } } ``` 使用代理对象: ``` public class Main { public static void main(String[] args) { UserService userService = new UserService(); ProxyFactory proxyFactory = new ProxyFactory(userService); UserService proxy = (UserService) proxyFactory.getProxyInstance(); proxy.addUser(); } } ``` 输出结果: ``` 方法执行前 添加用户 方法执行后 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JCJC错别字检测-田春峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值