程序员

前端 后端 移动端AOP的实现

2021-02-02  本文已影响0人  _铁马冰河_

AOP概念

前端实现(js)

由于语言特性,JavaScript本身就具有运行时动态插入逻辑的特性。函数可以接受一切形式函数,保存函数在利用call或者apply,即操作原型就可以。利用 Function.prototype 实现,具体代码如下:

<script type="text/javascript">
        var viewWillAppear = function () {
            console.log("页面即将展示");
        }

        Function.prototype.before = function (fn) {
            var self = this;
            return function(){
                fn.apply(self,arguments);
                return self.apply(this,arguments);
            }
        }

        Function.prototype.after = function (fn) {
            var self = this;
            return function(){
                var result = self.apply(this, arguments);
                fn.apply(this,arguments)
                return result;
            }
        }

     var viewWillAppear = viewWillAppear.before(function () {
            console.log("页面展示之前")
        }).after(function(){
            console.log("页面展示之后")
        })
    </script>
     
     //使用
     <input type="button" onclick="viewWillAppear()" value="展示页面">

在不改动原有业务代码的情况下,继续调用viewWillAppear函数。但是调用前后已经插入业务之外的代码了。

后端实现(java without spring)

模拟原有业务代码

DoAction doAction = new DoActionImpl();

AOPHandler aopHandler = new AOPHandler(doAction);

doAction.viewWillAppear();

使用代理模式实现AOP,新建AOPHandler类并实现InvocationHandler接口

public class AOPHandler implements InvocationHandler {

    private Object object;

    public AOPHandler(Object object) {
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("viewWillAppear执行前");

        Object ret = method.invoke(object,args);

        System.out.println("viewWillAppear执行后");
        return null;
    }
}

实现代理类之后只需在原有调用方法加入代理类如下:

DoAction doAction = new DoActionImpl();
AOPHandler aopHandler = new AOPHandler(doAction);
doAction = (DoAction)
 Proxy.newProxyInstance(DoActionImpl.class.getClassLoader(),
                        new Class[] { DoAction.class },
                        aopHandler);

doAction.viewWillAppear();

即在原有执行代码前后加入了业务代码

移动端实现 (iOS)

利用runtime 交换系统与自己定义方法的IMP,代码如下

SEL systemSel = @selector(viewWillAppear:);
SEL swizzSel = @selector(swiz_viewWillAppear:);
Method systemMethod = class_getInstanceMethod([self class], systemSel);
Method swizzMethod = class_getInstanceMethod([self class], swizzSel);


- (void)swiz_viewWillAppear:(BOOL)animated{
    //IMP已经被替换了
    NSLog(@"++viewwillappear之前")
    [self swiz_viewWillAppear:animated];
    NSLog(@"++viewwillappear之后")
}



不改变原有业务代码的情况下,系统调用viewwillappear的时候,已经加入业务之外的代码了。

总结

上一篇下一篇

猜你喜欢

热点阅读