如何用 node.js 做 AOP?

nug*_*har 7 javascript aop node.js

我在用 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);
Run Code Online (Sandbox Code Playgroud)

如您所见,我想监视唯一的函数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);
Run Code Online (Sandbox Code Playgroud)

这是我们的 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
});
Run Code Online (Sandbox Code Playgroud)

最后,我所要做的就是

node aop.js
Run Code Online (Sandbox Code Playgroud)

它有效,但正如您所看到的,存在一些代码入侵。我想摆脱它。有谁有想法吗?

k1r*_*r0s 6

我认为这是由于 Javascript 语言的性质——暗示了大量的代码入侵。

请不要:'(

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

我建议你使用kaop或TS版本ES7装饰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);
})
Run Code Online (Sandbox Code Playgroud)

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]
})
Run Code Online (Sandbox Code Playgroud)

我在 2018 年写了一篇文章,讨论了 JS 服务器端的 AOP。


Dan*_*try 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;
}
Run Code Online (Sandbox Code Playgroud)

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