【问题标题】:How to do AOP with node.js?如何用 node.js 做 AOP?
【发布时间】:2019-10-08 02:54:51
【问题描述】:

我在用 node.js 做一些 AOP 时遇到了一点问题: 假设我在名为 server.js 的脚本中有一个应用程序,我想监控它的功能。

代码如下:

var express = require('express');

var app = express();

app.get('/', function(req, res){
    res.setHeader('Content-Type', 'text/plain');
    res.end('Home');
});

app.get('/login', function(req, res){
    login(req,res);
    module.exports.login_(req, res);
});
app.use(function(req, res, next){
    res.setHeader('Content-Type', 'text/plain');
    res.send(404, 'Page introuvable !');
});

function login(req, res){
    res.setHeader('Content-Type', 'text/plain');
    res.end('Page de login');
}

app.listen(1616);

如您所见,我想监控独特的功能login(req, res)。为了做到这一点,我想在另一个脚本中使用 AOP,但我能找到的一切——我认为这是由于 Javascript 语言的性质——暗示了大量的代码入侵。

有没有办法像在 Spring/Java 中一样执行 AOP?无需进行任何代码入侵?

目前,我的解决方案是这样的:
这是我们的一些代码入侵的应用程序

    var express = require('express');

    var app = express();

    app.get('/', function(req, res){
        res.setHeader('Content-Type', 'text/plain');
        res.end('Home');
    });

    app.get('/login', function(req, res){

        //We need to use the function in module.exports
                    //--> code intrusion
        //login(req,res);
        module.exports.login_(req, res);
    });


    app.use(function(req, res, next){
        res.setHeader('Content-Type', 'text/plain');
        res.send(404, 'Page introuvable !');
    });


    function login(req, res){
        res.setHeader('Content-Type', 'text/plain');
        res.end('Page de login');
    }

    //We wrap here the function we want to monitor
    wrappedLogin = function(req, res){
        login(req, res);
    }

    module.exports = {
        login_ : wrappedLogin
    };


    app.listen(1616);

这是我们的 AOP 脚本

var aop = require("node-aop");

//Include the server
var server = require('./server.js');


aop.before(server, "login_", function(key, value){
        //I do some stuff here
});


aop.after(server, "login_", function(key, value){
        //I do some stuff here
});

最后,我要做的就是

node aop.js

它有效,但正如您所见,存在一些代码入侵。我想摆脱它。有人知道吗?

【问题讨论】:

    标签: javascript node.js aop


    【解决方案1】:

    我认为这是由于 Javascript 语言的性质 - 意味着 大量代码入侵。

    请不要:'(

    AOP是OOP的扩展,没有OOP就没有AOP。

    我建议你使用 kaop 或带有 ES7 装饰器的 TS 版本 kaop-ts

    1º:npm install kaop --save

    2º:定义一个建议来监控你的方法:

    import { reflect } from "kaop"
    
    const Log = reflect.advice(meta => {
      //meta.args contains the arguments {array}
       console.log(meta.methodName + " called");
       console.log("with arguments: " + meta.args);
       console.log("returned: " + meta.result);
    })
    

    3º 您必须按照 OOP 指南组织代码:

    const Controller = createClass({
      constructor: function(app){
        app.get('/', this.home);
        app.get('/login', this.login);
        app.use(this.notFound);
      },
      login: [function(req, res){
        //what ever
      }, Log],
      home: [function(req, res){
        res.setHeader('Content-Type', 'text/plain');
        res.end('Home');
      }, Log],
      notFound: [function(req, res){
        res.setHeader('Content-Type', 'text/plain');
        res.send(404, 'Page introuvable !');
      }, Log]
    })
    

    我在 2018 年写了一个 article 讨论 JS 服务器端的 AOP。

    【讨论】:

    • 这也适用于像(function(){var Foo = function(args) {/*...*/};Foo.prototype.bar = function(args){/*...*/};exports.Foo = Foo;})(); 这样编写的javascript 文件吗?这就是我正在查看的当前代码库的构造方式,我无法更改它。我也会对如何将其记录到文件中感兴趣,因为——我想我们都同意——在 Node.js 中登录到控制台并不是一种愉快的体验,尤其是在记录引用了父对象的对象时......
    • 我猜你可以扩展github.com/k1r0s/kaop/#get-started
    【解决方案2】:

    天真的尝试看起来像这样。

    var before = function(object, functionName, action) {
      var oldFunction = object.functionName;
      var newFunction = function() {
        action();
        oldFunction();
      };
      object.functionName = oldFunction;
    }
    
    var after = function(object, functionName, action) {
      var fn = object.functionName;
      var after = function() {
        fn();
        action();
      };
      object.functionName = oldFunction;
    }
    

    JS 非常灵活;您可以通过存储之后和之前的操作并根据需要添加/删除它们来轻松改进这一点,但至少这应该可以满足您的需求(尽管不是很好)。

    【讨论】:

    • 我实际上找到了一个解决方案(非常基本)。你可以在这里找到它:node-bakery
    【解决方案3】:

    为避免重新发明轮子,您可以使用 Nestjs,它是一个提供大量工具的框架。在其中你会找到做你想做的事的拦截器(我认为)。

    https://nestjs.com/

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-06
      相关资源
      最近更新 更多