- 浏览: 1328702 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (732)
- Java_about (146)
- Spring_Hibernate_Struts_OpenSource (27)
- linux_unix (62)
- life_sth (22)
- js_css_html_xml_nodejs (69)
- design_pattens (1)
- Perl (8)
- php_ecshop (4)
- DB_Mysql_Oracle_Informix_SqlServer (43)
- JSTL (8)
- Testing_自动化测试 (42)
- DB_ID_UUID (4)
- SEM_SEO (1)
- english_study_improvement (4)
- SVN_Git (9)
- WebService_SOA_CloudComputing (3)
- E-Commerce (1)
- Lucene_Solr (7)
- others (2)
- Regex (2)
- tomcat_jetty (8)
- zeroc-ice (1)
- java_excel (5)
- ant_maven_gradle (5)
- Unity_VR_AR_C# (2)
- jmeter (1)
- XPath_dom4j (1)
- Ruby_and_Rails (68)
- write_a_rails (17)
- manage_and_team (1)
- getting_real (1)
- ubuntu (20)
- git_and_git_flow (7)
- TODO (1)
- PM_design (2)
- Python_and_Django (8)
- NoSql_mongo_redis (24)
- C/C++ (3)
- vi_vim_gvim (0)
- c#_.Net_windows编程_dll (10)
- Php_and_Yii (9)
- Android_IOS (31)
- Mysql (5)
- sa_运维_network_硬件 (37)
- lua (2)
- c_cpp_VisualStudio (21)
- 硬件-RM-Arduino (6)
最新评论
-
shenkun58:
...
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
liaojia1:
正解,感谢
NoClassDefFoundError: Could not initialize springframework.BeanCreationException -
flingfox63:
谢谢分享,电脑上有IPV6,导致了Guard启动不了……
ruby错误解决: Address family not supported by protocol - connect(2) -
c39274936:
s = "hello_world_ruby" ...
驼峰格式和下划线格式转换_translation between camel and snake format -
yfj300:
学习了学习了学习了学习了
硬盘基本知识(磁道、扇区、柱面、磁头数、簇、MBR、DBR)
Rails源码阅读(三)Rails::Initializer
- 博客分类:
- write_a_rails
启动的落脚点
不论启动console还是启动server,最终都需要加载rails环境,这个落脚点在environment.rb中的Rails::Initializer.run
Rails::Initializer.run do |config| 。。。 end
启动前的配置Configuration
加载rails环境,需要的配置是比较多的,例如:启动的root_path,启动时要加载的frameworks,加载的路径,插件的位置,数据库的配置,log的配置,i18n的配置等等。这些都在Configuration类中配置。
# The Configuration class holds all the parameters for the Initializer and # ships with defaults that suites most Rails applications. But it's possible # to overwrite everything. Usually, you'll create an Configuration file # implicitly through the block running on the Initializer, but it's also # possible to create the Configuration instance in advance and pass it in # like this: # # config = Rails::Configuration.new # Rails::Initializer.run(:process, config) class Configuration 。。。 end
启动前再配置
def self.run(command = :process, configuration = Configuration.new) yield configuration if block_given? initializer = new configuration initializer.send(command) initializer end
# 在上面environment的启动中,configuration参数使用了默认的配置值Configuration.new
# 同时看到了,yield configuration if block_given?会把configuration传递给block,这样可以在启动时配置config的一些参数,而不用修改configuration类(这样也是可以的)
# 再回到上面的落脚点的代码,看到了这里的参数config原来就是configuration,也就是说想知道怎么配置config,需要了解configuration的内容和api。
好了,好多人跟我一样,困惑许久的config是什么,如何配置的问题,现在解决了。
启动1
继续往下看,这里有一句:initializer = new configuration
这种写法让我这种多年的javaer很反感,明明这么写更好理解么:initializer = Initializer.new(configuration)
javaer理解中的new是这样的:User user = new User(...)
initializer.send(command)
这里调用了实例方法command,根据command = :process知道,调用的方法是process方法。就是这里进入启动环节。
启动2 可以说,直接看这里就是rails的启动过程
# Sequentially step through all of the available initialization routines, # in order (view execution order in source). def process 。。。 end
启动3 仔细看看启动都做了些什么
check_ruby_version
检查版本,不对的话会报异常,详细略
install_gem_spec_stubs
看看stub的字样,表示这里的install其实是个“伪”install,目的是给plugin使用的。
说明:
This allows Gem plugins to depend on Rails even when the Gem version of Rails shouldn't be loaded
代码:
install_gem_spec_stubsGem.loaded_specs[stub] = Gem::Specification.new 。。。
set_load_path
配置$LOAD_PATH
说明:Set the $LOAD_PATH based on the value of Configuration
add_gem_load_paths
使用的对象为@gems
来源:configuration中的@gems << Rails::GemDependency.new(name, options)
调用了Rails::GemDependency的add_load_paths方法,这个方法内容主要使用了gem ‘some_gem' 'edition_n'
require_frameworks
依次执行 require ‘activesupport’ 等, 简而言之,这里才真正的require了,这里之后才真正可以使用这些framework
这里之后的方法,基本可以说能使用rails的这些组件了
set_autoload_paths
字面意义
把configuration里面的auto_load_paths 赋值给了ActiveSupport::Dependencies
关于ActiveSupport::Dependencies,以后再看看,暂不清楚内部原理
add_plugin_load_paths
主要由plugin_loader来
load_environment
这里会调用到所在环境(production,development,test)对应的rb文件
def environment_path "#{root_path}/config/environments/#{environment}.rb" end
并且把常量设置在了Object中(好处呢,首先是在任何地方都可以直接用了吧)
(self.class.constants - constants).each do |const| Object.const_set(const, self.class.const_get(const)) end
我在我的环境里看了看,果然常量增加了不少
#irb初始情况下: irb(main):011:0> Object.constants.size => 101 #我的rails环境 ?> Object.constants.size => 429
最后再重复一个问题,程序运行到这里,能不能使用rails的插件呢?
可以!例如active_support
但不全部,例如有些组建还要进行初始化操作,像active_record的数据库建立等
preload_frameworks
作用是为了Passenger/JRuby等使用
主要操作是显式调用各个组件的 framework.load_all! 方法
我看了看几个组件,居然是都有load_all!这个方法
module ActiveSupport def self.load_all! [Dependencies, Deprecation, Gzip, MessageVerifier, Multibyte, SecureRandom, TimeWithZone] end 。。。 end module ActiveRecord # TODO: Review explicit loads to see if they will automatically be handled by the initilizer. def self.load_all! [Base, DynamicFinderMatch, ConnectionAdapters::AbstractAdapter] end 。。。 end
initialize_encoding
这个类做了什么呢,怎么设置编码的呢?
Ruby1.8设置$KCODE
Ruby1.9默认是utf-8了
# For Ruby 1.8, this initialization sets $KCODE to 'u' to enable the # multibyte safe operations. Plugin authors supporting other encodings # should override this behaviour and set the relevant +default_charset+ # on ActionController::Base. # # For Ruby 1.9, this does nothing. Specify the default encoding in the Ruby # shebang line if you don't want UTF-8. def initialize_encoding $KCODE='u' if RUBY_VERSION < '1.9' end
initialize_database
这里才建立数据库连接了!!
也就是说从这里开始才能使用ActiveRecord来查询数据库
initialize_cache
放置缓存,页面缓存,块缓存等的地方
*1 如果默认位置: "#{root_path}/tmp/cache/"路径不存在则用内存了
def default_cache_store if File.exist?("#{root_path}/tmp/cache/") [ :file_store, "#{root_path}/tmp/cache/" ] else :memory_store end end
*2 这里从config得到了cache_store的类型,并初始化了一个cache_store
这里居然用了silence_wornings,很明显不让你随意设置咯
silence_warnings { Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store(configuration.cache_store) }
*3 cache_store的结果是返回一个cache_store对象,并不是一个配置
# Creates a new CacheStore object according to the given options. # # If no arguments are passed to this method, then a new # ActiveSupport::Cache::MemoryStore object will be returned. # # If you pass a Symbol as the first argument, then a corresponding cache # store class under the ActiveSupport::Cache namespace will be created. # For example: # # ActiveSupport::Cache.lookup_store(:memory_store)
initialize_framework_caches
这里只是简单的使用了上面设置的cache
def initialize_framework_caches if configuration.frameworks.include?(:action_controller) ActionController::Base.cache_store ||= RAILS_CACHE end end
initialize_logger
initialize_framework_logging
设置logger,如果config里面设置了logger,则基本跳过了。
*1 logger用的哪个类呢
logger = ActiveSupport::BufferedLogger.new(configuration.log_path)
*2 production的特殊配置
if configuration.environment == "production"
logger.auto_flushing = false
end
*3 logger leve 这里是默认的,可以在config里配置新的
def default_log_path File.join(root_path, 'log', "#{environment}.log") end def default_log_level environment == 'production' ? :info : :debug end
*4 可以给不同的组建单独配置其logger
这个在ide测试的时候有用,比如在test里,可以把active_record的log打入ide,便于调试
def initialize_framework_logging for framework in ([ :active_record, :action_controller, :action_mailer ] & configuration.frameworks) framework.to_s.camelize.constantize.const_get("Base").logger ||= Rails.logger end ActiveSupport::Dependencies.logger ||= Rails.logger Rails.cache.logger ||= Rails.logger end
initialize_dependency_mechanism
代理了类加载的机制,从而可以配置在开发环境和product环境中,加载类可以用不同的机制
# Sets the dependency loading mechanism based on the value of # Configuration#cache_classes. def initialize_dependency_mechanism ActiveSupport::Dependencies.mechanism = configuration.cache_classes ? :require : :load end
ActiveSupport::Dependencies这个类显然有很重要的地位,比如你看看大部分你用到的类都没有使用require ‘xxx’方法!!
initialize_whiny_nils
不用多说了,就是whiny_nil 的改写
initialize_time_zone
这个意图也清楚。但下面的代码没有弄明白具体含义,待补充吧。
设置adtive_record可以理解,但是最后一行,么意思呢。。。???
if configuration.frameworks.include?(:active_record) ActiveRecord::Base.time_zone_aware_attributes = true ActiveRecord::Base.default_timezone = :utc end
initialize_i18n
def initialize_i18n configuration.i18n.each do |setting, value| if setting == :load_path I18n.load_path += value else I18n.send("#{setting}=", value) end end end
#1 可见,如果配置了load_path则I18n类中加入这个路径;否则,认为是配置i18n的属性
#2 在config中可以这么配置:
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}')] # config.i18n.default_locale = :cn config.i18n.default_locale = 'zh_cn' config.i18n.load_path += Dir[ Rails.root.join('config', 'locales', 'user', '*.{rb,yml}'), Rails.root.join('config', 'locales', 'message', '*.{rb,yml}') ]
#3 最后,必须要说的是,这里用到了重写的ActiveSupport的类:
class Rails::OrderedOptions < Array 。。。 end
initialize_framework_settings
# Initializes framework-specific settings for each of the loaded frameworks # (Configuration#frameworks). The available settings map to the accessors # on each of the corresponding Base classes. def initialize_framework_settings configuration.frameworks.each do |framework| base_class = framework.to_s.camelize.constantize.const_get("Base") configuration.send(framework).each do |setting, value| base_class.send("#{setting}=", value) end end configuration.active_support.each do |setting, value| ActiveSupport.send("#{setting}=", value) end end
根据下面的注释,可以知道:
*1 某个framefork都有哪些项目可以配置?例如active_record
参考framefork的Base类
*2 配置的地方?
还是上面提到的,在environment的中配置
*3 配置怎么写?
# Show full error reports and disable caching config.action_controller.consider_all_requests_local = true config.action_view.debug_rjs = true #June: we can test cache here(comment 2 lines && uncomment 3 lines after) config.action_controller.perform_caching = false config.action_view.cache_template_loading = false
*4 为什么可以这么写?
还是需要明白Rails::OrderedOptions也就是ActiveSupport::OrderedOptions的用法
*5 active_support应该没有base类咯,看出来了么
initialize_framework_views
基本上可以同上。
initialize_metal
请看metal的用法吧
add_support_load_paths
空方法???
check_for_unbuilt_gems
这里可以安装config中配置到gem
load_gems
使用config中的gem
# pick up any gems that plugins depend on
add_gem_load_paths
load_gems
check_gem_dependencies
load_application_initializers
config/initializers目录下面的文件会在rails server启动最后顺序执行,顺序为文件名排序,所以有依赖关系的话,就得提前安排一下,例如db:migrate那样加入时间戳么。总之在这里安排顺序就是个很懒的设计了。
看看源码:
def load_application_initializers if gems_dependencies_loaded Dir["#{configuration.root_path}/config/initializers/**/*.rb"].sort.each do |initializer| load(initializer) end end end
方法没有叫做after_initialize,因为这里安排的仍然是app启动的一项
after_initialize
这里才是启动之后的操作,回调。
例如这里可以给分页的插件中文话。
initialize_database_middleware
这里会检查配置的session_store情况,如果配置了下面的目标内容,就会用数据库来存session了
ActionController::Base.session_store.name == 'ActiveRecord::SessionStore' (去配置config)
prepare_dispatcher
# Prepare dispatcher callbacks and run 'prepare' callbacks
看样子好像是加载了dispatcher并define_dispatcher_callbacks(configuration.cache_classes)
这里设置了@@cache_classes = cache_classes
作用:
# In the development environment your application's code is reloaded on # every request. This slows down response time but is perfect for development # since you don't have to restart the webserver when you make code changes. config.cache_classes = false
initialize_routing
代码:
# If Action Controller is not one of the loaded frameworks (Configuration#frameworks) # this does nothing. Otherwise, it loads the routing definitions and sets up # loading module used to lazily load controllers (Configuration#controller_paths). def initialize_routing return unless configuration.frameworks.include?(:action_controller) ActionController::Routing.controller_paths += configuration.controller_paths #### Me added this line ### ActionController::Routing::Routes.add_configuration_file(File.join("/home/lijg/workrubygit/t8", 'config', 'routes2.rb')) ActionController::Routing::Routes.add_configuration_file(configuration.routes_configuration_file) ActionController::Routing::Routes.reload! end
这里的作用:
*1 知晓controller的位置,等需要的时候去得到这个类
*2 知晓routes文件的位置,load it
这里的文件,可以是多个的,内部是可以处理的
configuration_files.each { |config| load(config) }
*3 reload!
def load! Routing.use_controllers!(nil) # Clear the controller cache so we may discover new ones clear! load_routes! end # reload! will always force a reload whereas load checks the timestamp first alias reload! load!
*4 加入一些自己想要的controller
有时候想测试一个需求(不用git哦),想加入一些自己的routes和mvc看看情况,这个时候就可以用这个了。
这里仅仅是个小实验,所以简单修改了下源码。
*5 注意这里的顺序,路由加入的时候,优先加入的会先匹配。这样我的测试路由优先加入比较好~
load_observers
这个是给active_record使用的ActiveRecord::Base.instantiate_observers
看看里面的代码:
"#{observer} must be a lowercase, underscored class name (or an instance of the class itself) responding to the instance method. Example: Person.observers = :big_brother # calls BigBrother.instance"
load_view_paths
这两个组件在用view的路径
ActionController::Base.view_paths.load!
ActionMailer::Base.view_paths.load!
load_application_classes
*1 如果设置了某些自动加载的路径,这时会加载
例如在env中这样的设置:config.load_paths << "#{RAILS_ROOT}/app/middleware"
*2 加载了这个目录以及子目录下的所有.rb文件
Dir.glob("#{load_path}/**/*.rb"
*3 这里加载方式:require_dependency
# Eager load application classes def load_application_classes return if $rails_rake_task if configuration.cache_classes configuration.eager_load_paths.each do |load_path| matcher = /\A#{Regexp.escape(load_path)}(.*)\.rb\Z/ Dir.glob("#{load_path}/**/*.rb").sort.each do |file| require_dependency file.sub(matcher, '\1') end end end end
写到这里,我想需要把rails2的自动加载路径打印出来看看
--------------------------------------------------
/home/lijg/workrubygit/t8/app/controllers/
/home/lijg/workrubygit/t8/app
/home/lijg/workrubygit/t8/app/models
/home/lijg/workrubygit/t8/app/controllers
/home/lijg/workrubygit/t8/app/helpers
/home/lijg/workrubygit/t8/lib #看见了,这个在rails2是自动加入的,但rails3好像不同了
/home/lijg/workrubygit/t8/vendor
/home/lijg/workrubygit/t8/config/../vendor/rails/railties/lib/../builtin/rails_info/
/home/lijg/workrubygit/t8/app/middleware #这个是我自己设置的
--------------------------------------------------
disable_dependency_loading
用到了这个:ActiveSupport::Dependencies.unhook!
本篇完毕
作业:需要再仔细看看的
require_dependency
auto_load
ActiveSupport::Dependencies
----本篇完毕---- -----EOF---- ----THE END----
。
。
。
+
o
o
o
评论
sorry阿,这里暂时占了个位置,还是没有那么多时间一下子写完了~待续~
发表评论
-
Rails外如何启动rails的类自动加载_activates autoloading using ActiveSupport 3.x
2016-06-22 12:08 701The following cod ... -
Rails源码阅读(13)rails中的autoload和ruby的autoload
2014-07-30 17:13 2005Rails源码阅读(13)rails中的autoload和 ... -
Rails源码阅读(12)叫Rails的模块module_Rails常量使用
2014-07-02 09:35 1134The module nams "Rail ... -
Rails源码阅读(11)Rails使用bundle保持多机器环境gem版本的一致性
2013-09-05 19:21 1530Rails源码阅读(11)Rails使用bundle ... -
Rails源码阅读(十)在console 使用ActionController::Integration::Session
2012-05-05 14:48 1816Rails源码阅读(十)在console 使用Actio ... -
Rails源码阅读(九)ActionView::Base_用户请求在rails中的处理流程(4)
2012-04-08 18:19 2258Rails源码阅读(九)ActionView::Base_用户 ... -
Rails源码阅读(八)ActionController::Base_用户请求在rails中的处理流程(3)
2012-04-06 23:01 1779Rails源码阅读(八)Actio ... -
Rails源码阅读(七)ActionController::Dispatcher_用户请求在rails中的处理流程(2)
2012-04-06 22:25 1420Rails源码阅读(七)Actio ... -
动手写rails(二)Rails_Ruby_ERB使用_模板_定制
2012-04-07 20:46 2622动手写rails(二)Rails_Ruby_ERB使用_模板_ ... -
Rails源码阅读(六)ActionController::Dispatcher_用户请求在rails中的处理流程(1)
2012-03-28 00:17 1762Rails源码阅读(六)ActionController::D ... -
Rails源码阅读(零)_config/boot
2012-03-15 11:56 1836不论是script/console 还是 script/ser ... -
动手写rails(一)_Rack标准和HttpServer之WEBrick
2012-03-15 07:22 2137无论如何,最终的结果是要启动一个server来接受请求, ... -
Rails源码阅读(五)with_scope 和 named_scope
2012-02-02 15:24 1491Rails源码阅读(四)with_scope and name ... -
Rails源码阅读(四)gem_rubygems之require_Rails_require_深入理解(一)
2011-11-16 10:39 2175Rails源码阅读(四)rubygems之require_Ra ... -
Rails源码阅读(二)_script/server
2011-09-17 18:51 1471Rails源码阅读(二)_script/server ... -
Rails源码阅读(一)_script/console
2011-09-05 11:13 2170Rails源码阅读_script/console启动 ...
相关推荐
白色大气风格的建筑商业网站模板下载.rar
内容概要:本文详细介绍了面向对象编程语言Objective-C的基础语法,包括其历史背景、特点、环境搭建、基本语法、面向对象编程、高级特性和实际应用。具体涵盖的内容包括Objective-C的历史发展、面向对象编程的核心特性、变量和数据类型、控制结构、函数、数组和字典的使用,以及类、对象、属性和方法的定义与使用。此外,还介绍了高级特性如协议和委托、类别和扩展、ARC、块和GCD。最后,通过示例项目展示了如何在Xcode中创建和调试Objective-C程序,以及如何使用Cocoa和Cocoa Touch框架。 适合人群:具备一定的编程基础,希望学习或深入了解Objective-C编程的开发人员。 使用场景及目标:适用于需要开发macOS和iOS应用的开发者,帮助他们掌握Objective-C的基本语法和高级特性,提高编程效率和代码质量。 其他说明:本文不仅提供了详细的理论讲解,还通过实际代码示例展示了如何在Xcode中创建和调试Objective-C项目,适合初级到中级水平的开发人员学习和参考。
本次开发的微信小程球馆预约系统,有管理员,用户两个角色。管理员功能有个人中心,用户管理,场地类型管理,球馆信息管理,球馆预约管理,系统管理。用户可以在微信小程序上面注册登录,查看球馆信息,对球馆进行预约操作。 开发本程序后台用到了SSM开发技术,微信端用的是uni-app技术。数据库采用关系数据库市场占有率最高的MySQL作为本程序使用的数据库,完全符合程序使用并且有丰富的拓展余地。 用户在微信小程序注册登录后可以看到首页,首页可以搜索球馆名称,也可以查看球馆资讯,下面是导航栏。 用户点击球馆信息可以进行预约,预约需要输入相关时间等信息。 我的里面可以修改个人信息,可以退出,还可以查看球馆预约信息和我的收藏信息。
1、嵌入式物联网单片机项目开发例程,简单、方便、好用,节省开发时间。 2、代码使用KEIL 标准库开发,当前在STM32F030C8T6运行,如果是STM32F030其他型号芯片,依然适用,请自行更改KEIL芯片型号以及FLASH容量即可。 3、软件下载时,请注意keil选择项是jlink还是stlink。 4、有偿指导v:wulianjishu666; 5、如果接入其他传感器,请查看账号发布的其他资料。 6、单片机与模块的接线,在代码当中均有定义,请自行对照。 7、若硬件有差异,请根据自身情况调整代码,程序仅供参考学习。 8、代码有注释说明,请耐心阅读。 9、编译时请注意提示,请选择合适的编译器版本。
廖鹏盛 - 时代进行曲.zip
白色大气风格的人体艺术摄影网站模板下载.zip
白色大气风格的服装设计师模板下载.zip
白色大气风格的景观设计HTML网站模板.zip
优质的机器学习资源是当今科技领域的热点,其中TensorFlow作为谷歌公司的开源库,成为最受欢迎的深度学习框架之一,广泛应用于各类项目中。TensorFlow提供了丰富的功能和灵活性,使得开发者可以轻松构建和训练复杂的神经网络模型,处理图像、文本和其他类型的数据。由于其开源性质,拥有庞大的社区支持,用户可以放心使用,并从开源社区中获取宝贵的经验和资源。 mnist数据集是机器学习领域的经典数据集之一。它包含着大量的手写数字图像,供开发者用来训练和测试各种算法和模型。这个数据集的规模相对较小,因此对于绝大多数人来说,无论是数据的下载还是训练过程,都不会对电脑性能提出过高的要求。这使得mnist成为了理想的入门数据集,适合初学者探索和理解机器学习算法的基本原理。 结合Pygame与TensorFlow,你将能够为机器学习实验创建出图形化界面,以及实现交互式处理。Pygame是一款面向游戏和多媒体应用的Python库,但同样也可以用于数据可视化和图形化交互。利用Pygame,你可以展示训练过程中的图像输出、模型的预测结果等,增强对机器学习算法运行情况的直观认识。而且,Pygame的简单。内
基于两种坐标系的超螺旋滑模观测器的永磁同步电机pmsm无位置(速度)传感器控制模型 支持 dq旋转坐标系和静止坐标系建立smo 引入二阶滑模超螺旋算法替代一阶滑模 dq坐标系引入锁相环PLL估计转速及转子位置 有效削弱抖振 赠送超螺旋滑模搭建推导文档及相关参考资料 仿真模型
汇编实验算数运算程序设计.docx
小区监控视频监控方案.doc
白色大气风格的HTML商务模板下载.zip
白色大气风格响应式运动健身瑜伽企业网站模板.zip
单片机实验仿真设计报告
白色大气风格的设计公司整站网站模板下载.zip
白色大气风格的html商务模板.zip
白色大气风格的英文网站模板下载.zip
白色大气风格的科研教育模板下载.zip
本摄像头ov7670驱动程序已经通过本人的验证可以正常运行,不同的stm32开发板只需要修改引脚即可使用