前端 后端 移动端AOP的实现

AOP概念

  • 一种程序设计范式
  • 不是OOP的替代品,只是对OOP的一种补充
  • 从主业务中脱离出来横向切面关注点,降低与业务耦合

前端实现(js)

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


     
     //使用
     

在不改动原有业务代码的情况下,继续调用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的时候,已经加入业务之外的代码了。

总结

  • 隔离业务之外的代码,降低耦合
  • hook原有方法,侵入性小。C函数的hook可以使用fishhook
  • 减少开发量,方便复用
  • 代码不集中,可能会散落在项目各个位置

你可能感兴趣的:(前端 后端 移动端AOP的实现)