`
yarmyarch
  • 浏览: 2461 次
  • 性别: Icon_minigender_1
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

js实现的AOP雏形

阅读更多
  老早以前的东西了,发出来分享下。目前支持aop的框架实在很少,功能也挺残废的~ 运行还算稳定,不会对this指针造成干扰,经测试可对对象的方法、独立函数、构造函数等各种添加AOP支持,也可以解除AOP支持。使用advice链式结构实现,最大的特点应该是支持参数/返回值控制(即每个advice均有一个入口/出口,可以自由定制输入/输出策略)。不多说了,上代码,直接拿来用应该是木有问题的但是目前还只实现了before和after两个joinpoint,后续可能扩展一些,参数/返回值策略也有些小单调虽然扩展性不咋地但是基本需求应该能满足。后续如果有时间的话可能从这两点完善一下。

//外部接口

var AopUtil = {};

(function() {

    AopUtil.ALLOW_IN = 1;

    AopUtil.ALLOW_OUT = 2;

    var original = {};

    //缓存数据,新增before advice的时候会用到

    var beforeAdviceCounter = 0;

    //将原始方法变成代理方法的方法

    var createProxyMethod = function(originalItem) {

        return function() {

            var currentArg = arguments;

            var currentReturn = arguments;

            var lastReturn = arguments;

            //计算组合策略(参数+返回值策略)中的参数策略

            //isInAllowed为策略值二进制表示中的最低位值,isOutAllowed为次低位

            var isInAllowed, isOutAllowed;

            //当前函数的返回值

            var result;

            for (var i in originalItem.adviceChain) {

                //读取策略组

                isInAllowed = originalItem.adviceChain[i].strategy;

                isOutAllowed = isInAllowed >> 1;

                isInAllowed = isInAllowed - (isInAllowed >> 1 << 1);

                isOutAllowed = isOutAllowed - (isOutAllowed >> 1 << 1);

                if (isInAllowed) currentArg = lastReturn;

                else currentArg = arguments;

                currentReturn = [originalItem.adviceChain[i].method.apply(this, currentArg)];

                if (isOutAllowed) lastReturn = currentReturn;

            }

            return lastReturn[0];

        }

    }

    //对原始方法添加AOP支持

    var attachToAop = function(methodName, strategy) {

        if (original[methodName])  return null;

        var sourceMethod = eval(methodName);

        if (!sourceMethod) return null;

        //初始化adviceChain

        original[methodName] = {};

        original[methodName].backup = sourceMethod;

        original[methodName].adviceChain = [{method : sourceMethod, strategy : strategy}];

        eval(methodName  + " = createProxyMethod(original[methodName])");

    }

    //外部接口之添加before joinpoint

    AopUtil.before = function(methodName, command, strategy) {

        if (!original[methodName]) attachToAop(methodName, 3);

        original[methodName].adviceChain.splice(

            beforeAdviceCounter, 0, {

                method : command,

                strategy : (strategy ? strategy : AopUtil.SKIP_ARG)

            }

        );

        ++beforeAdviceCounter;

    }

    //外部接口之添加after joinpoint

    AopUtil.after = function(methodName, command, strategy) {

        //原始函数两端全开

        if (!original[methodName]) attachToAop(methodName, 3);

        original[methodName].adviceChain.push({

            method : command,

            strategy : (strategy ? strategy : AopUtil.SKIP_ARG)

        });

    }

    //清空目标方法上的所有advice

    AopUtil.clearAdvice = function(methodName) {

        if (original[methodName]) {

            eval(methodName + "= original[methodName].backup");

            original[methodName] = null;

        }

    }
})();



靠,在这个编辑器里头调格式真够累的...下面是使用实例



//先定义一个类

var Class = function() {

    //私有成员变量

    var value = "value";

    this.alert = function() {

        alert(value);

    }

    this.setValue = function(newValue) {

        value = newValue;

    }

}

AopUtil.before("Class", function() {

    alert("你正在初始化一个实例!");

});

//初始化一个实例,这个时候会输出"你正在初始化一个实例!"这句话;

//实际上,当直接执行"Class()"的时候也会输出这句话。如果仅希望在Class被当做构造函数使用时输出,

//可以通过this指针来判断,就像这样:

//AopUtil.before("Class", function() {

//    if (!typeof(this).toLowerCase() == "object") alert("你没有把Class当做构造函数!");

//    else alert("你正在初始化一个实例!");

//});

var a = new Class();

//比较高级的应用:

AopUtil.before("a.alert", function() {

    alert(0);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

AopUtil.before("a.alert", function() {

    alert(1);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

AopUtil.before("a.alert", function() {

    alert(2);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

AopUtil.after("a.alert", function() {

    alert(3);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

AopUtil.after("a.alert", function() {

    alert(4);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

AopUtil.after("a.alert", function() {

    alert(5);

}, AopUtil.ALLOW_IN + AopUtil.ALLOW_OUT);

//有兴趣的同僚们觉得执行"a.alert()"的时候应该输出啥?
2
2
分享到:
评论

相关推荐

    使用Spring的注解方式实现AOP的细节

    本篇文章将深入探讨如何通过Spring的注解方式实现AOP的细节。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切点(Pointcut)定义了哪些方法会被通知(Advice...

    利用C#实现AOP常见的几种方法详解

    在C#中,实现AOP的方法多种多样,以下将详细介绍几种常见的实现方式。 1. **静态织入**: 静态织入是在编译时完成的,它通过编译器或者编译插件(如PostSharp)在目标类的代码中插入拦截逻辑。这种方式的优点是...

    Xml配置实现AOP

    XML配置是Spring框架中非常重要的组成部分,特别是在实现面向切面编程(AOP)时。AOP是一种设计模式,它允许我们定义横切关注点,并将其与业务逻辑分离,从而提高代码的可维护性和复用性。下面将详细探讨在XML配置中...

    Asp.net Core 3.1基于AspectCore实现AOP实现事务、缓存拦截器功能

    在net core2.2时,我当时就尝试过用autofac实现aop,但这次我不想用autofac,我用了一个更轻量级的框架,AspectCore。 用起来非常非常的简单,但一开始还是走了一点弯路,主要是网上都是net core3以下的教程,3以下...

    基于注解实现SpringAop

    基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop

    反射实现 AOP 动态代理模式(Spring AOP 的实现原理)

    动态代理是实现AOP的一种常用技术,它允许在运行时创建代理对象,拦截对真实对象的调用,并在调用前后添加额外的行为。 在Java开发中,反射机制是实现动态代理的关键技术之一。反射提供了在运行时访问和操作类的...

    用Java动态代理实现AOP

    Java动态代理实现AOP Java动态代理是实现Aspect Oriented Programming(AOP)的重要手段。在Java中,动态代理可以通过java.lang.reflect InvocationHandler接口和java.lang.reflect.Proxy类来实现。AOP的主要思想...

    Xml文件配置实现AOP通知

    环绕通知稍微复杂一些,因为它需要实现`org.springframework.aop.MethodInterceptor`接口,并覆写`invoke()`方法。以下是一个简单的环绕通知示例: ```java public class AroundAdvice implements ...

    android 实现AOP 使用Aspectj Kotlin版Demo.zip

    这个"android 实现AOP 使用Aspect Kotlin版Demo"就是一个实例,展示了如何在Kotlin中利用AspectJ进行AOP编程。 首先,我们要了解AOP的基本概念。面向切面编程的核心在于“切面”和“通知”。切面是关注点的模块化,...

    Spring实现AOP的4种方式 - Java -

    在Java编程领域,Spring框架以其强大的功能和灵活性深受开发者喜爱,尤其在面向切面编程(AOP)方面,Spring提供了多种实现方式。AOP是一种编程范式,它允许程序员定义“切面”,这些切面可以封装关注点,如日志、...

    EJB+Annotation实现AOP的DEMO

    这篇博客"使用EJB+Annotation实现AOP的DEMO"主要介绍了如何在EJB中利用注解(Annotation)来实现AOP的功能。在Java EE中,EJB 3.0及后续版本引入了大量的注解,使得开发者可以免去编写XML配置文件,直接在代码中声明...

    Unity结合三导实现依赖注入跟AOP

    2. Unity AOP:Unity提供了对AOP的支持,可以通过拦截器(Interceptor)实现。拦截器是实现AOP的核心,它在方法调用前后执行自定义逻辑。 3. 创建拦截器:通过继承`IInterceptor`接口或使用`Unity.Interception`库...

    AOP使用CGLIB实现AOP功能

    Spring AOP实现方法之一:CGLIB 实现AOP功能

    Spring实现AOP的4种方式

    本篇文章将详细探讨Spring实现AOP的四种主要方法:基于代理的方式、基于AspectJ的注解方式、基于XML的AOP配置以及基于Java的AOP配置。 1. 基于代理的实现 Spring的AOP支持两种代理类型:JDK动态代理和CGLIB代理。...

    反射实现 AOP 动态代理模式(Spring AOP 的实现 原理) - Java 例子 -

    Spring框架是Java中实现AOP的一个流行工具,它通过动态代理机制实现了这一功能。本文将深入探讨Spring AOP的实现原理,以及如何使用反射来实现动态代理模式。 首先,我们需要了解AOP的基本概念。AOP的核心思想是切...

    注解方式实现AOP编程

    AOP通常用于实现横切关注点,如日志记录、事务管理、权限检查等,这些功能在多个类或方法中都有可能出现。在Spring框架中,AOP的实现有两种主要方式:一种是基于XML配置,另一种是基于注解。本篇将主要讨论如何通过...

    Spring 基于基于XML配置方式实现AOP

    本篇文章将重点讲解如何通过XML配置方式在Spring中实现AOP。 首先,了解AOP的基本概念是必要的。AOP的核心是切面(Aspect),它封装了多个相关操作,形成了一个关注点。切点(Pointcut)定义了这些操作应用到何处,...

    Java实现aop案例

    这篇博客文章《Java实现aop案例》可能详细介绍了如何在Java项目中使用Spring AOP来实现面向切面编程。虽然没有具体的描述,但我们可以根据标题推测文章可能会涵盖以下内容: 1. **AOP基本概念**:介绍AOP的核心概念...

    C# 实现 AOP微型框架

    C#实现AOP微型框架是将面向切面编程(Aspect-Oriented Programming)的理念应用于C#编程中的一个实践。在VS2008环境下开发的这个框架,为开发者提供了一种方便的方式来插入横切关注点,如日志、事务管理、性能监控等...

    JavaEE spring自动实现AOP代理

    Spring 提供了两种方式来实现AOP代理:JDK动态代理和CGLIB代理。 1. **JDK动态代理**: - JDK动态代理基于Java的接口实现,适用于目标对象实现了接口的情况。Spring会为这个接口创建一个代理类,代理类在调用真实...

Global site tag (gtag.js) - Google Analytics