本文是基于express 3.4.6 的

1.在我们的app.js 文件里面有这么几行

 

http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

这个其实是调用http模块 的 createServer 函数创建一个服务,然后监听端口的。

2. 我们再去看看express 的入口文件 

/**
* Module dependencies.
*/ var connect = require('connect')
, proto = require('./application')
, Route = require('./router/route')
, Router = require('./router')
, req = require('./request')
, res = require('./response')
, utils = connect.utils; /**
* Expose `createApplication()`.
*/ exports = module.exports = createApplication; /**
* Expose mime.
*/ exports.mime = connect.mime; /**
* Create an express application.
*
* @return {Function}
* @api public
*/ function createApplication() {
var app = connect();
//将application中的方法全部拷贝到connect对象上去。
utils.merge(app, proto);
//设置app 的request对象的原型为req,本身的属性为connect对象
app.request = { __proto__: req, app: app };
//设置app的response对象原型为res ,本身的属性为connect对象
app.response = { __proto__: res, app: app };
//调用application中的方法init
app.init();
return app;
} /**
* Expose connect.middleware as express.*
* for example `express.logger` etc.
*/
/**
* 加载connect模块中得所有中间件
*/
for (var key in connect.middleware) {
Object.defineProperty(
exports
, key
, Object.getOwnPropertyDescriptor(connect.middleware, key));
} /**
* Error on createServer().
*/
/**
* 将创建服务器的方法输出
* @returns {Function}
*/
exports.createServer = function(){
console.warn('Warning: express.createServer() is deprecated, express');
console.warn('applications no longer inherit from http.Server,');
console.warn('please use:');
console.warn('');
console.warn(' var express = require("express");');
console.warn(' var app = express();');
console.warn('');
//加载创建应用程序的方法,开始创建application
return createApplication();
}; /**
* Expose the prototypes.
*/ exports.application = proto;
exports.request = req;
exports.response = res; /**
* Expose constructors.
*/ exports.Route = Route;
exports.Router = Router; // Error handler title exports.errorHandler.title = 'Express';

可以看到exports = module.exports = createApplication;将这个作为模块导出了,作为一个构造函数。

这个函数是: 

function createApplication() {
var app = connect();
//将application中的方法全部拷贝到connect对象上去。
utils.merge(app, proto);
//设置app 的request对象的原型为req,本身的属性为connect对象
app.request = { __proto__: req, app: app };
//设置app的response对象原型为res ,本身的属性为connect对象
app.response = { __proto__: res, app: app };
//调用application中的方法init
app.init();
return app;
}

首先调用connect 组件app,于是将proto 上该有的方法都拷贝到app上去。proto是神马么?它就是  proto = require('./application')  application.js 输出的“app” 对象 所有得函数,

接着将req,res 作为 组件app 的request,response 的原型,同时将app作为他们的一个属性,为什么要这么做呢?后面就会看到。最后调用app.init()方法,这个其实是调用application

中的init方法。

3.application.js

app.init = function(){
this.cache = {};
this.settings = {};
this.engines = {};
//默认配置
this.defaultConfiguration();
};

我们看到他是直接调用defaultConfiguration 方法的。我们再去看看defaultConfiguration方法的实现

app.defaultConfiguration = function(){
// default settings
this.enable('x-powered-by');
this.enable('etag');
this.set('env', process.env.NODE_ENV || 'development');
this.set('subdomain offset', 2);
debug('booting in %s mode', this.get('env')); // implicit middleware
//调用中间件
this.use(connect.query());
this.use(middleware.init(this)); // inherit protos
//继承原型
this.on('mount', function(parent){
this.request.__proto__ = parent.request;
this.response.__proto__ = parent.response;
this.engines.__proto__ = parent.engines;
this.settings.__proto__ = parent.settings;
}); //router
//路由
this._router = new Router(this);
this.routes = this._router.map;
this.__defineGetter__('router', function(){
this._usedRouter = true;
this._router.caseSensitive = this.enabled('case sensitive routing');
this._router.strict = this.enabled('strict routing');
return this._router.middleware;
}); // setup locals
this.locals = locals(this); // default locals
this.locals.settings = this.settings; // default configuration
this.set('view', View);
this.set('views', process.cwd() + '/views');
this.set('jsonp callback name', 'callback'); this.configure('development', function(){
this.set('json spaces', 2);
}); this.configure('production', function(){
this.enable('view cache');
});
};

从代码中可以看到,它首先调用中间件,中间件的作用主要是改写改写request,response 请求的。将这2个请求导出,方便后面的模板渲染。然后再调用路由模块。路由模块只要是根据path

调用路由分发函数分发路由,执行callback,最后调用view 模块,渲染我们的模板。

最新文章

  1. Mac ping localhost 地址变化
  2. Linux下Nagios的安装与配置[转]
  3. JAVA——getter setter
  4. hdu 4726 Kia's Calculation
  5. NGINX server配置中if的用法
  6. codevs 3305 水果姐逛水果街Ⅱ
  7. Mysql Innodb体系结构
  8. 2964:日历问题-poj
  9. LibreOJ NOI Round #1 Day 1 B. 失控的未来交通工具
  10. JMeter测试(菜鸟级,高手莫点)
  11. 推荐一篇关于java集合的博文,写的很nice
  12. Android-创建一个简单的用户接口-(补day2内容)
  13. css图片的全屏显示代码-css3
  14. Hadoop "Cannot create directory .Name node is in safe mode."解决方案
  15. Xcode 备忘
  16. Java的并发编程中的多线程问题到底是怎么回事儿?
  17. C++对带有分隔符的字符串 分割为数字的通用解决方案
  18. maven项目中的报错问题——Dynamic Web Module 3.0 requires Java 1.6 or newer.
  19. C#阻止系统休眠
  20. 利用AbstractRoutingDataSource实现动态数据源切换

热门文章

  1. table中的标题行冻结的简单实现
  2. (转)字符编码笔记:ASCII,Unicode和UTF-8
  3. Linux下运行jar包
  4. Windows,linux快捷键
  5. postgresql 配置文件优化
  6. http://www.cnbeta.com/articles/306769.htm
  7. WPF学习开发客户端软件-任务助手(已上传源码)
  8. 实验四 时序逻辑电路的VHDL设计
  9. 插件~使用ECharts动态在地图上标识点~动态添加和删除标识点
  10. paip.哈米架构CAO.txt