.Net下AOP的应用(1)--也说IoC与AOP

来源:互联网 发布:js同源策略是什么 编辑:程序博客网 时间:2024/05/16 18:56

Martin Flower提出把IoC命名为Dependency Injection(依赖注入)模式2004年初开始,就开始倍受关注。我们先不管名称上的变化,实际上它解决的解决方案还是一个“解耦”的老问题,灵活性和可扩展性是一个永远的话题。IoC把接口和实现解耦,实现可配置。这里不再对IoC的各种方式的注入方式展开了,具体的可以参看Martin FlowerInversion of Control Containers and the Dependency Injection pattern

AOP(Aspect Oriented Programming,译为“面向方面编程”),这里最主要是要理解什么是“方面”(Aspect),根据我的理解,所谓“方面”就是一个功能点,比如日志处理功能,事务处理功能,安全认证功能等等;这稍微有别与“服务”,相对而言 “方面”是与业务逻辑不太相关的,而“服务”则不做这种区分。这样“方面”从逻辑从剥离出来,“方面”就可以在一处编写,到处被引用,提高了代码的复用性;同样在程序的开发过程中使业务逻辑实现者不用关注“方面”这部分所要实现的非逻辑代码;同样也提高了“方面”的可扩展性,加入AOP,实现可配置,修改 “方面”这部分的实现,那就不用在原先的逻辑代码中到处修改而只修改或更换“方面”就可以了。那么什么时候把“方面”链接到主逻辑代码中,怎样链接呢?

先来看第一个问题,一般链接可以采用编译时链接,也可以在代码执行时链接,AOP采用了后者。

第二个问题,AOP采用了Dynamic Proxy(动态代理)来解决如何链接问题,Dynamic Proxy是通过动态生成程序集技术实现的,说白了就是一个类是作为委托方,而通过Dynamic Proxy动态生成一个从委托方类继承的代理类。所以我们要使用这个代理类时,都是从IoC容器取得,而取得的类实例则是这个在容器里通过Dynamic Proxy动态生成的代理类的实例,我们先抛去Dynamic Proxy如何动态生成这部分,那么上面从容器里取得代理类实例的过程相当与一条这样的赋值语句:

ClassA objA=new DerivedA();//这里DerivedA类是从ClassA继承。

从这里我们可以看到,所要被配上“方面”的Method应该时virtual方法,所以我们可以看到很多地方,需要被配上“方面”的类,都抽出一个或者几个接口再被继承,除了有接口编程的选项外,也有这方面的考虑。“方面”也是在生成代理类时被加入进去的。

那“方面”又是按照什么规则被Dynamic Proxy生成代码加入到生成的代理类里面去的呢?这里面就有这样几个概念:

Target object:目标对象,就是要使用“方面”的类,就像上文的ClassA

Joinpoint:连接点,这是“方面”要被使用的地方,是ClassA中的一个方法或者是抛异常点

Pointcut:是一组连接点,比如由正则表达是确定的一组Joinpoint

Advice:截获器,可以说是AspectTarget Object的连接器,Advice调用Aspect的代码,Advice通过一定的规则加到Joinpoint上。Advice一般有:

Before advice:在Joinpoint之前执行Aspect

After advice:在Joinpoint之后执行Aspect

Around advice是上两种的复合,之前之后都执行Aspect

Throws advice:如果发生异常则执行Aspect,异常类型可以指定

有了上面的基础部件在,那么IoC容器读入配置文件后,取得了上面的信息,然后,把这些东西交给Dynamic Proxy来生成代理类,Dynamic Proxy找到Target ObjectJoinpoint所在的Method,然后把对advice调用加入到此方法中去。当然Dynamic Proxy不是把所有的Advice类代码再重新生成到目标Method里面去,而是通过委托代理机制,把Method委托给Advice,因为从包含关系上来看,Advice包含了Target Object的对目标方法的调用。

这样AOP就可以在Aspect注入的情况下实现其业务与Aspect功能分离的功能了。

在以后的时间内,我想就Spring.NetAspect#(Castle)EDRA(微软社区出的)的AOP解决方案做一点学习,如果您有这方面的经验和心得,欢迎交流哦。

原创粉丝点击