不可不说,静态语言的源码看起来确实比较方便,以前看python的源码但是很累的。python
journey的入口函数在main.go
中,main()
函数作了如下几件事:git
设置了GOMAXPROCS
为CPU核数github
使用flag
读取命令行配置sql
初始化数据库database.Initialize()
,看下Initialize()
源码:数据库
func Initialize() error { // 若是journey.db不存在,查找Ghost数据库并转换它 if !helpers.FileExists(filenames.DatabaseFilename) { // Convert Ghost database if available (time format needs to change to be compatible with journey) migration.Ghost() } // 打开或者建立一个数据库 var err error readDB, err = sql.Open("sqlite3", filenames.DatabaseFilename) if err != nil { return err } readDB.SetMaxIdleConns(256) // TODO: is this enough? err = readDB.Ping() if err != nil { return err } currentTime := time.Now() // 看下stmtInitialization语句可知,若是不存在相应的表才会建立。 // 后面跟的参数用于填充stmtInitialization中的占位符,占位符是问号`?`。 _, err = readDB.Exec(stmtInitialization, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime, uuid.Formatter(uuid.NewV4(), uuid.CleanHyphen), currentTime, currentTime) // TODO: Is Commit()/Rollback() needed for DB.Exec()? if err != nil { return err } err = checkBlogSettings() if err != nil { return err } return nil }
生成博客首页基本信息methods.GenerateBlog()
,生成的Blog
对象是全局变量,只会生成一次:json
func GenerateBlog() error { // 写锁定全局Blog变量 if Blog != nil { Blog.Lock() defer Blog.Unlock() } // 从数据库读取博客,database.RetrieveBlog()使用预先定义好的sql语句获取内容,生成blog对象。 blog, err := database.RetrieveBlog() if err != nil { return err } // 添加数据库中没有保存的参数。 // 从配置文件中获取博客的首页链接。 blog.Url = []byte(configuration.Config.Url) //这个是干吗的? blog.AssetPath = assetPath // 建立导航栏的slugs,slug即页面的惟一标识符,可用在url上。 for index, _ := range blog.NavigationItems { blog.NavigationItems[index].Slug = slug.Generate(blog.NavigationItems[index].Label, "navigation") } Blog = blog return nil }
模板编译(不是渲染哦)templates.Generate()
,后面的文章会分析编译流程。服务器
加载插件plugins.Load()
。plug的官方介绍:https://github.com/kabukky/journey/wiki/Creating-a-Journey-Plugin函数
从配置文件(config.json)读取http/https监听端口。ui
从配置文件读取服务器启动方式。有AdminOnly
,All
,default
三种,默认是default
,下面看下default
作了哪些事:this
httpRouter := httptreemux.New() // 注册博客路由 server.InitializeBlog(httpRouter) server.InitializePages(httpRouter) // 注册admin路由 server.InitializeAdmin(httpRouter) // 启动HTTP server,它使用的服务go使用标准库的http包。 log.Println("Starting server without HTTPS support. Please enable HTTPS in " + filenames.ConfigFilename + " to improve security.") log.Println("Starting http server on port " + httpPort + "...") err := http.ListenAndServe(httpPort, httpRouter) if err != nil { log.Fatal("Error: Couldn't start the HTTP server:", err)
路由的注册流程将在后面的文章中介绍。