﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-差沙的密码 -- SSHWSFC's code</title><link>http://www.blogjava.net/sshwsfc/</link><description>阅读本Blog请自备塑料袋一只</description><language>zh-cn</language><lastBuildDate>Tue, 28 Apr 2026 20:43:32 GMT</lastBuildDate><pubDate>Tue, 28 Apr 2026 20:43:32 GMT</pubDate><ttl>60</ttl><item><title>Google Developer Day 收获</title><link>http://www.blogjava.net/sshwsfc/archive/2008/06/15/208023.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Sun, 15 Jun 2008 05:03:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2008/06/15/208023.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/208023.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2008/06/15/208023.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/208023.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/208023.html</trackback:ping><description><![CDATA[前些天去参加了Google的开发日活动，由于之后直接就去郊区所以一直没有时间写blog来谈谈感想。首先是google的OpenSocial，进入大厅签到之后转角过去就是个大网站的展台，每个柱子的一面是一个网站，都是OpenSocial的合作网站，有聚友，天际，天涯等。有幸跟聚友的CTO谭晓生先生和天际网的CTO郭应寿先生聊了聊OpenSocial使用中的益处和遇到的问题，感觉OpenSocial目前还是不太成熟，对比FB来说还有一定的差距，比如没有照片处理等等问题。而且我始终有一种感觉，OpenSocial是一个google的标准，但是各大网站在使用OpenSocial的时候几乎都会加上自己的扩展，这样下去，最终OpenSocial统一平台的目标很难实现，因为两个网站的Gidget几乎不能通用，这些问题OpenSocial的合作网站跟Google也在讨论中。另外得到的消息是，OpenSocial可能也会考虑出一套XXml，规范化OpenSocial的使用，并借此加强安全性。<br />
稍后的OpenSocial专题topic中了解到了更多有关OpenSocial的信息，主要是Shindig了, 前一天还在跟白衣提议用ss做一个类似Shindig的东西，主要是做一个OpenSocial的实现，当时就想这玩意估计有了，但是没想到是host到apache了，在apache的孵化器中大家可以自己找找。会议的时候逮住了一个google的人问了一堆问题，过后才知道原来是google中国sns的负责人。<br />
最大的收获实在是太意外了，在中午休息的时候，走过过道到楼下吃饭，突然发现一个熟悉的身影坐在角落里一个人在玩电脑，我晕是Andy Rubin，Android的老大。居然就坐在那里，而且旁边的人没有人在意他，要知道听android topic的人可不少呀，居然每一个人认出他来的。我叫了朋友确认一下，准备上前打招呼。刚上去打了个招呼，握了个手，又来了一个人，他一下认出Andy，并且跟Andy简短的交谈了一下。我提议先照个相，照相后简短聊下那个人就走了。过后Andy说那个人就是Google中国负责android的老大邸烁博士，我狂晕呀两位老大都让我给碰上了。稍候跟Andy聊了一下Android的发展，随后他掏出一个android的原型机，就是google IO大会上的那种机器。这里要说明的是，不管在模拟器上android的表现如何，在真机上你的体验绝对绝对是不一样的，太COOL了。尤其是第二屏的widget效果，还有那个street view效果，真机拿在手上体验就是不一样呀～～～～ 随后又了解到了一些android目前的发展情况，这里可以告诉大家的是，android是绝对值得期待的～！！！
<div><img src="http://www.blogjava.net/images/blogjava_net/sshwsfc/IMG_008011.jpg" width="800" height="600" alt="" /><br />
</div>
<img src ="http://www.blogjava.net/sshwsfc/aggbug/208023.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2008-06-15 13:03 <a href="http://www.blogjava.net/sshwsfc/archive/2008/06/15/208023.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android上的MSN初见成效～～！！</title><link>http://www.blogjava.net/sshwsfc/archive/2008/03/21/187605.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Thu, 20 Mar 2008 17:59:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2008/03/21/187605.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/187605.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2008/03/21/187605.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/187605.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/187605.html</trackback:ping><description><![CDATA[<p>经过两天的努力，终于在Android上面跑起来MSN了。现在实现了基本的聊天功能，打算陆续的把其他功能完善，万事开头难，相信以后的工作会很顺利。</p>
<p><br />
Gtalk的功能由于有官方支持，早就弄了跟这个差不多的版本。</p>
<p><br />
另外，这个软件目前是以插件的形式开发，多一个协议就是多一个apk，实现一些intent即可。官方的IM包里面有很多支持，可惜文档没有提及。</p>
<p><img alt="" src="http://www.androidcn.net/attachments/month_0803/20080321_b41709e0a0efac3b972eAokluMybAz14.jpg" border="0" /></p>
<p>&nbsp;</p>
<p><a href="http://www.androidcn.net/thread-252-1-1.html" target="_blank">Android中文论坛原帖</a></p><img src ="http://www.blogjava.net/sshwsfc/aggbug/187605.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2008-03-21 01:59 <a href="http://www.blogjava.net/sshwsfc/archive/2008/03/21/187605.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Air+Ext小试一下</title><link>http://www.blogjava.net/sshwsfc/archive/2008/02/26/182206.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Tue, 26 Feb 2008 05:49:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2008/02/26/182206.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/182206.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2008/02/26/182206.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/182206.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/182206.html</trackback:ping><description><![CDATA[<p>今天看到Air1.0和Ext2.0.2的发布消息，很是兴奋，要知道Ext的每个版本升级都是很实惠的。</p> <p>Ext2.0.2的这次升级主要是针对Air的支持，看来他们的关系是越来越近了，我也借机小试了一下Air。</p> <p>简单说说Air的开发过程：<br></p> <p>1.先要下载jre 和 airSDK</p> <p>2.jre就不说了，airSDK也是简单的解压一下便可。</p> <blockquote> <p>可以看看SDK下面的bin目录，一共俩文件，一个adl一个adt，adl是用来测试的，adt使用编辑发布的（ADT怎么让我想起来android了）</p></blockquote> <p>3.创建一个普通的目录作为项目目录。OK，可以写页面了。就是写html js flash什么的，都可。</p> <p>4.编写一个xml文件，名字不限。内容嘛～～～～</p> <blockquote> <p>看看这个文件，airSDK\templates\descriptor-template.xml 里面有详细的解释，拿过来改改即可，给一个例子：</p> <hr> <pre><span style="color: #0000ff">&lt;?</span>xml version="1.0" encoding="UTF-8"<span style="color: #0000ff">?&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">application</span> <span style="color: #ff0000">xmlns</span>=<span style="color: #0000ff">"http://ns.adobe.com/air/application/1.0.M6"</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">id</span><span style="color: #0000ff">&gt;</span>examples.html.HelloWorld<span style="color: #0000ff">&lt;/</span><span style="color: #800000">id</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">version</span><span style="color: #0000ff">&gt;</span>0.1<span style="color: #0000ff">&lt;/</span><span style="color: #800000">version</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">filename</span><span style="color: #0000ff">&gt;</span>HelloWorld<span style="color: #0000ff">&lt;/</span><span style="color: #800000">filename</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;</span><span style="color: #800000">initialWindow</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">content</span><span style="color: #0000ff">&gt;</span>HelloWorld.html<span style="color: #0000ff">&lt;/</span><span style="color: #800000">content</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">visible</span><span style="color: #0000ff">&gt;</span>true<span style="color: #0000ff">&lt;/</span><span style="color: #800000">visible</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">width</span><span style="color: #0000ff">&gt;</span>400<span style="color: #0000ff">&lt;/</span><span style="color: #800000">width</span><span style="color: #0000ff">&gt;</span>
        <span style="color: #0000ff">&lt;</span><span style="color: #800000">height</span><span style="color: #0000ff">&gt;</span>200<span style="color: #0000ff">&lt;/</span><span style="color: #800000">height</span><span style="color: #0000ff">&gt;</span>
    <span style="color: #0000ff">&lt;/</span><span style="color: #800000">initialWindow</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">application</span><span style="color: #0000ff">&gt;</span></pre>
<p>
<hr>

<p></p></blockquote>
<p>5.运行airSDK\bin\adl.exe (那个创建的xml文件名)，运行即可。</p>
<p>PS:我一般用eclipse来编辑，用外部命令的工具来运行adl，很方便。</p>
<p>简单的说了一下Air的开发方法后，我们来简单的看一下Ext都对Air提供了什么支持。</p>
<p>1.Ext.air.FileProvider</p>
<blockquote>
<p>Ext提供状态保存的功能，在对AIr的支持中Ext实现了一个Provider，这个Provider把状态保存在本地目录的一个文件里。使用方法如下：</p>
<hr>
<pre><span style="color: #008000">// Initialize the state provider</span>
Ext.state.Manager.setProvider(<span style="color: #0000ff">new</span> Ext.air.FileProvider({
	file: 'ext.state',
	<span style="color: #008000">// if first time running</span>
	defaultState : {
		mainWindow : {
			width:400,
			height:200,
			x:10,
			y:10
		}
	}
}));</pre>
<p>
<hr>

<p></p>
<p>制定Provider为Ext.air.FileProvider即可，这个操作一般在onReady里面执行。当然需要你先创建一个ext.state文本文件，在程序根目录下即可。这样ext的应用运行时，窗口等大小的调整，位置之类的调整都能保存下来了。很方便。</p>
<p>这里包装的Air代码主要是：</p>
<p>air.File.applicationStorageDirectory.resolvePath</p>
<p>air.FileStream</p>
<p>等</p></blockquote>
<p>2.Ext.air.NativeWindow</p>
<blockquote>
<p>Ext可以调用Air实现Native的窗口。使用方法如下：</p>
<hr>
<pre>	<span style="color: #0000ff">var</span> win = <span style="color: #0000ff">new</span> Ext.air.NativeWindow({
		id: 'mainWindow',
		instance: <span style="color: #0000ff">window</span>.nativeWindow,
		minimizeToTray: <span style="color: #0000ff">true</span>,
		trayIcon: 'ext-air/resources/icons/extlogo16.png',
		trayTip: 'Simple Tasks',
		trayMenu : [{
			text: 'Open Simple Tasks',
			handler: <span style="color: #0000ff">function</span>(){
				win.activate();
			}
		}, '-', {
			text: 'Exit',
			handler: <span style="color: #0000ff">function</span>(){
				air.NativeApplication.nativeApplication.exit();
			}
		}]
	});</pre>
<p>
<hr>

<p></p>
<p>我们可以看到，其中最吸引人的是系统托盘的功能，可以方便的指定系统托盘的各种属性。</p>
<p>这里包装的主要是：</p>
<p>window.runtime.flash.html.HTMLLoader.createRootWindow</p>
<p>air.Screen.mainScreen.visibleBounds</p></blockquote>
<p>3.Ext.sql.Connection</p>
<blockquote>
<p>这个是重头戏，对db的支持，我们知道Air的DB是采用sqlite3来实现的。Ext封装了Air的db操作，简化统一了一些，而且提供了Store的支持，非常强大：</p>
<p>让我们简单看一下用法：</p>
<p><strong><em>首先取得connection</em></strong></p>
<p>var conn = Ext.sql.Connection.getInstance();</p>
<p><strong><em>而后打开db</em></strong></p>
<p>conn.open('ext.db');//这里的文件如果不存在会自动创建</p>
<p><strong><em>创建Table</em></strong></p>
<hr>
<pre>        conn.createTable({
            <span style="color: #0000ff">name</span>: 'user',
            key: 'userId',
            fields: [
			    {<span style="color: #0000ff">name</span>: 'userId', type:'string'},
			    {<span style="color: #0000ff">name</span>: '<span style="color: #0000ff">name</span>', type:'string'},
			    {<span style="color: #0000ff">name</span>: 'pwd', type:'string'},
			    {<span style="color: #0000ff">name</span>: 'email', type:'string'}
			]
    	});</pre>
<hr>
</blockquote>
<blockquote dir="ltr" style="margin-right: 0px">
<p><strong><em>取得一个Table</em></strong></p>
<p>var userDao = conn.getTable('user','userId');</p>
<p><strong><em>查询</em></strong></p>
<p>var users = userDao.select();//这里可以写条件式</p>
<p><strong><em>添加</em></strong></p>
<hr>
<pre><span style="color: #0000ff">var</span> newuser = {
    userId : 'sshw',
    <span style="color: #0000ff">name</span> : 'sshwsfc',
    pwd : 'test',
    email : 'sshwsfc@gmail.com'
} 

userDao.insert(newuser);</pre>
<p>
<hr>

<p></p>
<p>感觉使用上还是蛮不错的，大家可以一点点试试看。</p>
<p>值得一提的是，在源码中发现Connection这里设计成了工厂的模式，Connection是一个伪接口，实现除了Air的还有GoogleGear的，会根据所处环境选择，灰常的好。</p></blockquote>
<p dir="ltr">功能还在研究中，有心得了一点点给大家分享，</p>
<p dir="ltr">PS:打算搞一个iphone的信息管理软件练练手。反正都是sqlite的</p> <img src ="http://www.blogjava.net/sshwsfc/aggbug/182206.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2008-02-26 13:49 <a href="http://www.blogjava.net/sshwsfc/archive/2008/02/26/182206.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Django什么情况(1) -- Model的&amp;ldquo;造Class&amp;rdquo;概述</title><link>http://www.blogjava.net/sshwsfc/archive/2008/02/02/179019.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Sat, 02 Feb 2008 09:32:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2008/02/02/179019.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/179019.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2008/02/02/179019.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/179019.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/179019.html</trackback:ping><description><![CDATA[<p>在朋友和同事的极力推荐下最近开始看上了python,其实主要是还是因为python是2007年度语言,怎么的也要与时俱进呀.最近一路看来有些心得,希望能与大家分享,小弟其实也只接触不到一周的python,有说错的地方还望大家指出改正.</p> <p>不打算从py的语法基础说起了,直接说说对django的心得:</p> <p>接触django首先需要了解可能就是他那个model，建立一个model就什么都有了，这对于搞java得人员来说还是挺有吸引力的（当然貌似对于动态语言这都是小儿科），那么让我们先看一个model的例子：</p> <p>偷懒了，直接拿django-admin里面的User出来了</p> <hr> <pre><span style="color: #0000ff">class</span> User(models.Model): 
    username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric])) 
    first_name = models.CharField(_('first <span style="color: #0000ff">name</span>'), maxlength=30, blank=True) 
    last_name = models.CharField(_('last <span style="color: #0000ff">name</span>'), maxlength=30, blank=True) 
    email = models.EmailField(_('e-mail address'), blank=True) 
    password = models.CharField(_('password'), maxlength=128)) 
    <span style="color: #0000ff">class</span> Meta: 
        ordering = ('username',)</pre>
<hr>

<p>每个属性就是一个库表的字段，定义起来非常简单明了，models里面提供了很多种类的Field类似上面的EmailField。不同的Field有不同的设置，可以看相应的原来来了解相关的设置．</p>
<p>在model class内部还有一个class Meta，这个Class的属性制定了这个表的一些存取策略，例如这里的ordering。MetaClass里面的属性可以用model的_meta属性取得。OK，那么这样一个model怎么就能实现对数据库表的灵活操作了呢。让我们来看看吧。</p>
<p>首先先分析一下/django/django/db/models/base.py这个文件，其中包含了models.Model这类的定义：</p>
<p>看看class定义的第一行吧，第一行就够我琢磨一阵子的了：</p>
<hr>
<pre><span style="color: #0000ff">class</span> Model(<span style="color: #0000ff">object</span>):
    __metaclass__ = ModelBase</pre>
<hr>

<p>Model采用了new style class定义，关于这个内容大家可以放狗看一下，第一行是一个__metaclass__属性的定义，该属性的值是ModelBase，这是一个类。__metaclass__的意思是，指定一个class，这个class的实例就是本class，相信您已经晕了。那么就拿这个Model的例子来说明一下，如果没有__metaclass__这个属性，产生一个实例就是正常的流程，有了这个属性流程会有改变：</p>
<p>首先调用BaseModel.__new__(cls, name, bases, attrs)这个方法，回返回的值是一个class类型，然后用这个class来创建实例。其实BaseModel就是Model的元类，来制定Model这个类的最终样子。关于元类的更多信息请看<a href="http://wiki.woodpecker.org.cn/moin/MetaClassInPython" target="_blank">这里</a></p>
<p>那么我们的目光一下转移到BaseModel这个类上，我有种直觉，Meta这个class最后可以用_meta来取就是在这里做的手脚，看一下BaseModel的定义吧，有点长：</p>
<hr>
<pre><span style="color: #0000ff">class</span> ModelBase(type):
    "<span style="color: #8b0000">Metaclass for all models</span>"
    <span style="color: #0000ff">def</span> __new__(cls, <span style="color: #0000ff">name</span>, bases, attrs):
        # If this isn't a subclass of Model, don't do anything special.</pre><pre>        <span style="color: #0000ff">if</span> <span style="color: #0000ff">name</span> == 'Model' or not filter(lambda b: issubclass(b, Model), bases):    <strong>#1</strong>
            <span style="color: #0000ff">return</span> super(ModelBase, cls).__new__(cls, <span style="color: #0000ff">name</span>, bases, attrs)

        # Create the <span style="color: #0000ff">class</span>.</pre><pre>        new_class = type.__new__(cls, <span style="color: #0000ff">name</span>, bases, {'__module__': attrs.pop('__module__')})    <strong>#2</strong></pre><pre>        new_class.add_to_class('_meta', Options(attrs.pop('Meta', None)))     <strong>#3</strong></pre><pre>        new_class.add_to_class('DoesNotExist', <span style="color: #0000ff">types</span>.<span style="color: #0000ff">ClassType</span>('DoesNotExist', (ObjectDoesNotExist,), {}))

        # Build complete list of parents                                      #4
        for base in bases:
            # TODO: Checking for the presence of '_meta' is hackish.
            <span style="color: #0000ff">if</span> '_meta' in dir(base):
                new_class._meta.parents.append(base)
                new_class._meta.parents.extend(base._meta.parents)

        model_module = <span style="color: #0000ff">sys</span>.<span style="color: #0000ff">modules</span>[new_class.__module__]

        <span style="color: #0000ff">if</span> getattr(new_class._meta, 'app_label', None) is None:
            # Figure out the app_label by looking one level up.
            # For 'django.contrib.sites.models', this would be 'sites'.
            new_class._meta.app_label = model_module.__name__.<span style="color: #0000ff">split</span>('.')[-2]  #5

        # Bail out early <span style="color: #0000ff">if</span> we have already created this <span style="color: #0000ff">class</span>.
        m = get_model(new_class._meta.app_label, <span style="color: #0000ff">name</span>, False)                 #6
        <span style="color: #0000ff">if</span> m is not None:
            <span style="color: #0000ff">return</span> m

        # Add all attributes to the <span style="color: #0000ff">class</span>.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)                             #7

        # Add Fields inherited from parents
        for parent in new_class._meta.parents:
            for field in parent._meta.fields:
                # Only <span style="color: #0000ff">add</span> parent fields <span style="color: #0000ff">if</span> they aren't defined for this <span style="color: #0000ff">class</span>.
                try:
                    new_class._meta.get_field(field.<span style="color: #0000ff">name</span>)
                except FieldDoesNotExist:
                    field.contribute_to_class(new_class, field.<span style="color: #0000ff">name</span>)          #8

        new_class._prepare()

        register_models(new_class._meta.app_label, new_class)                 #9
        # Because of the way imports happen (recursively), we may or may not be
        # the first <span style="color: #0000ff">class</span> for this model to <span style="color: #0000ff">register</span> with the framework. There
        # should only be one <span style="color: #0000ff">class</span> for each model, so we must always <span style="color: #0000ff">return</span> the
        # registered <span style="color: #0000ff">version</span>.
        <span style="color: #0000ff">return</span> get_model(new_class._meta.app_label, <span style="color: #0000ff">name</span>, False)              #10</pre>
<p>
<hr>

<p></p>
<p>简单分析一下这个代码：</p>
<p>1. 检查class是否为Model的子类，不是的话，不做任何处理，直接传给父类处理，也就相当于正常的处理了class，注意super在多重继承的时候应该严格使用 </p>
<p>2. 用type来创建类，创建的就是正常的ModelClass</p>
<p>3. 这句很重要，add_to_class是Model里面的class方法，这个方法其实就是传入name和value，给Model添加class属性.看到了，原来神奇的_meta就是这么来的. 提到add_to_class方法，简单看一下它的代码：</p>
<hr>
<pre>    <span style="color: #0000ff">def</span> add_to_class(cls, <span style="color: #0000ff">name</span>, value):
        <span style="color: #0000ff">if</span> <span style="color: #0000ff">name</span> == 'Admin':
            assert type(value) == <span style="color: #0000ff">types</span>.<span style="color: #0000ff">ClassType</span>, "<span style="color: #8b0000">%r attribute of %s model must be a class, not a %s object</span>" % (<span style="color: #0000ff">name</span>, cls.__name__, type(value))
            value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() <span style="color: #0000ff">if</span> not k.startswith('_')]))
        <span style="color: #0000ff">if</span> hasattr(value, 'contribute_to_class'):
            value.contribute_to_class(cls, <span style="color: #0000ff">name</span>)
        <span style="color: #0000ff">else</span>:
            setattr(cls, <span style="color: #0000ff">name</span>, value)
    add_to_class = classmethod(add_to_class)</pre>
<p>
<hr>
最后一句是制定这个方法是class方法，特点就是方法的第一个参数是本class，其实classmethod就是一个装饰器，在2。4之后可以使用@来简写。这里不得不提的是他对Admin的特殊处理，虽然AdminOption不是在admin模块里面的，但是这么做还是跟一个Admin的东东绑定起来了，在java的世界解耦是一件大事，看到下面还有对'contribute_to_class'这个方法的特殊处理，django为啥不弄的解耦点呢。而且同样是包装成Option，一个是在BaseModel里面弄（那个Meta的包装），一个在add_to_class方法里面弄，实在有点不优雅，可能还没了解太多，不知道他的深度用意吧。</p>
<p>4. Meta的集成，Option的这个类提供继承方法</p>
<p>5. 取得applabel，就是把model的名字分割取到数第二个，我很喜欢-2这样的设定</p>
<p>6. get_model方法取得缓存里面的东西。</p>
<p>7. 把所有的class attr拿出来搞一遍，一般的属性就setattr弄回去了，要是这个属性有contribute_to_class这个callable属性，那就执行之（Admin的处理完全也可以这样，其实我们常用的objects就是用这个方法弄的）</p>
<p>8. 每个Field调用自己的contribute_to_class方法来进行特殊的处理</p>
<p>9. 进入缓存，，暂且叫缓存吧，里面的东西大家看看很简单 文件在 /django/django/db/models/loading.py 里面还是有很多内容的</p>
<p>10.看注释说的很清楚了，我们一定要在缓存里面拿model。</p>
<p>&nbsp;</p>
<p>其中需要指出的是，new_class._prepare() 这个方法，简单列出片段：</p>
<hr>
<pre>    <span style="color: #0000ff">def</span> _prepare(cls):
        # Creates some methods once self._meta has been populated.
        opts = cls._meta
        opts._prepare(cls)

        ．．．．

        dispatcher.send(signal=signals.class_prepared, sender=cls)</pre>
<hr>

<p>中间省略了一些代码，不是我没看懂的就是没意思的，关键要看这个dispatcher呀。这里是监听者模式，dispatcher.send(signal=signals.class_prepared, sender=cls)放松了一个包含特定信号的事件，让监听的人可以做相应的处理。这样的信号还有很多种，我们可以很简单的截获信号，处理相应的内容。也许您还记得，在我们创建db的时候，会提示创建一个超级用户，其实就是用这个方法来弄的。</p>
<p>那我为什么要把这个单独拿出来说呢，因为监听这个事件的人不是别人，是"objects"！！！在文件/django/django/db/models/manager.py的开头就有这样的代码：</p>
<hr>
<pre><span style="color: #0000ff">def</span> ensure_default_manager(sender):
    cls = sender
    <span style="color: #0000ff">if</span> not hasattr(cls, '_default_manager'):
        # Create the default manager, <span style="color: #0000ff">if</span> needed.
        try:
            cls._meta.get_field('objects')
            raise ValueError, "<span style="color: #8b0000">Model %s must specify a custom Manager, because it has a field named 'objects'</span>" % cls.__name__
        except FieldDoesNotExist:
            pass
        cls.add_to_class('objects', Manager())

dispatcher.connect(ensure_default_manager, signal=signals.class_prepared)</pre>
<p>
<hr>
</p>
<p>定义了一个callable，然后监听signals.class_prepared信号，呵呵，连上了吧，只要Class准备好了，就调用这个方法。简单判断有没有_default_manager'属性和meta里面的objects后，开始插入objects。cls.add_to_class('objects', Manager()) 很熟悉吧，前面讲过不多说了。</p>
<p>PS：写到这里不由得感叹，为啥同样是往Class里面加入东东，要搞这么多的花样呢，我以前也写过一个Rails配置加载过程的<a href="http://www.blogjava.net/sshwsfc/archive/2006/11/20/82401.html" target="_blank">分析文档</a>，虽然一个简单的加载配置就把所有动态语言玩个遍，但是这也太不规范了吧，可能不这么玩就不算&#8220;动态&#8221;语言了吧，哈哈。</p>
<p>&nbsp;</p>
<p>终于Model的Class造好了，相信大家以后造自己的Class也能玩出更多的花样。那么可以开始下一步了。我到老家后再写吧，打算讲讲神奇的objects，也就是Manager，其实就是玩QuerySet。。那里有很多的__xxx__方法，很好很强大</p>   <img src ="http://www.blogjava.net/sshwsfc/aggbug/179019.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2008-02-02 17:32 <a href="http://www.blogjava.net/sshwsfc/archive/2008/02/02/179019.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Android发布, Android中国网站正式成立, 欢迎访问</title><link>http://www.blogjava.net/sshwsfc/archive/2007/11/15/160736.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Thu, 15 Nov 2007 05:41:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2007/11/15/160736.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/160736.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2007/11/15/160736.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/160736.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/160736.html</trackback:ping><description><![CDATA[<a class="external text" title="http://code.google.com/android" href="http://code.google.com/android" rel="nofollow">Android</a>是google为手机开发的操作系统, 基于Linux2.6内核.
<p><br />
2007年11月12日(北美时间), Android的APP SDK公布, 开始了google手机的<a class="external text" title="http://code.google.com/android" href="http://code.google.com/android" rel="nofollow">开发大赛</a>. 我们致力于Android的开发文档翻译, 开发技术交流等工作, 希望为Android平台在中国的推广贡献自己的力量. <br />
</p>
<br />
Andorid的SDK是完全针对java设计的, 甚至提供eclipse的插件, 作为一个javaer不研究实在可惜.<br />
<br />
现在中文文档已经有了初步进展,&nbsp; 大家翻译的热情都很高涨. 论坛里的讨论也十分热烈, 欢迎您的访问.<br />
<br />
我们的网站, <a href="http://www.androidcn.net">http://www.androidcn.net</a><br />
<br />
中文文档计划:<br />
<br />
<a href="http://www.androidcn.net/wiki">http://www.androidcn.net/wiki</a><br />
<br />
<span style="font-size: 10pt; color: #c0c0c0">PS: 管理员您好, 不知道这个符不符合首页发布的规则, 要是不妥我会撤下, 我们都想为Android中文化贡献力量</span>
<img src ="http://www.blogjava.net/sshwsfc/aggbug/160736.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2007-11-15 13:41 <a href="http://www.blogjava.net/sshwsfc/archive/2007/11/15/160736.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Ext的组件结构分析,附Ext组件结构图</title><link>http://www.blogjava.net/sshwsfc/archive/2007/10/20/154539.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Sat, 20 Oct 2007 12:01:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2007/10/20/154539.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/154539.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2007/10/20/154539.html#Feedback</comments><slash:comments>25</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/154539.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/154539.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 相信大家看了Ext2.0后, 印象最深的应该是Ext的组件模式,很好的规范了组件设计,用Manager的统一管理,也是很好的方式.下面简单分析一下Ext的组件结构.&nbsp;&nbsp;<a href='http://www.blogjava.net/sshwsfc/archive/2007/10/20/154539.html'>阅读全文</a><img src ="http://www.blogjava.net/sshwsfc/aggbug/154539.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2007-10-20 20:01 <a href="http://www.blogjava.net/sshwsfc/archive/2007/10/20/154539.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBPM的Token路径问题</title><link>http://www.blogjava.net/sshwsfc/archive/2007/04/24/113217.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Tue, 24 Apr 2007 08:04:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2007/04/24/113217.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/113217.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2007/04/24/113217.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/113217.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/113217.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 12pt">ProcessInstance里面有一个findToken(String tokenPath)方法。这里面写的是tokenPath。 tokenPath跟文件系统的规则差不多。类似 /fork1/fork2 这样的。<br><br>那么，怎么到fork2下的一个分支token ？<br><br>token自己也有findToken这个方法，不同的是ProcessInstance的是以rootToken为起点，token自己的是以自己为起点。那么取到token2下面的分支<br><br>token2.findToken("token") <br>如果有返回token，没有返回null <br><br><br>至于token的名字，我刚才查源码才发现，只有在Fork节点才会给token赋予名字。。。 <br><br>那么token2.findToken("token") 这里"token"那里来 <br><br>命名的规则，如下。。&nbsp;<br><br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;tokenName&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br><img id=Codehighlighter1_63_394_Open_Image onclick="this.style.display='none'; Codehighlighter1_63_394_Open_Text.style.display='none'; Codehighlighter1_63_394_Closed_Image.style.display='inline'; Codehighlighter1_63_394_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_63_394_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_63_394_Closed_Text.style.display='none'; Codehighlighter1_63_394_Open_Image.style.display='inline'; Codehighlighter1_63_394_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(&nbsp;transitionName&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;)&nbsp;</span><span id=Codehighlighter1_63_394_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_63_394_Open_Text><span style="COLOR: #000000">{<br><img id=Codehighlighter1_114_158_Open_Image onclick="this.style.display='none'; Codehighlighter1_114_158_Open_Text.style.display='none'; Codehighlighter1_114_158_Closed_Image.style.display='inline'; Codehighlighter1_114_158_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_114_158_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_114_158_Closed_Text.style.display='none'; Codehighlighter1_114_158_Open_Image.style.display='inline'; Codehighlighter1_114_158_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(&nbsp;</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">&nbsp;parent.hasChild(&nbsp;transitionName&nbsp;)&nbsp;)&nbsp;</span><span id=Codehighlighter1_114_158_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_114_158_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokenName&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;transitionName;<br><img id=Codehighlighter1_165_388_Open_Image onclick="this.style.display='none'; Codehighlighter1_165_388_Open_Text.style.display='none'; Codehighlighter1_165_388_Closed_Image.style.display='inline'; Codehighlighter1_165_388_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_165_388_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_165_388_Closed_Text.style.display='none'; Codehighlighter1_165_388_Open_Image.style.display='inline'; Codehighlighter1_165_388_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_165_388_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_165_388_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokenName&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;transitionName&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;Integer.toString(&nbsp;i&nbsp;);<br><img id=Codehighlighter1_293_380_Open_Image onclick="this.style.display='none'; Codehighlighter1_293_380_Open_Text.style.display='none'; Codehighlighter1_293_380_Closed_Image.style.display='inline'; Codehighlighter1_293_380_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_293_380_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_293_380_Closed_Text.style.display='none'; Codehighlighter1_293_380_Open_Image.style.display='inline'; Codehighlighter1_293_380_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;(&nbsp;parent.hasChild(&nbsp;tokenName&nbsp;)&nbsp;)&nbsp;</span><span id=Codehighlighter1_293_380_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_293_380_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokenName&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;transitionName&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;Integer.toString(&nbsp;i&nbsp;);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_401_556_Open_Image onclick="this.style.display='none'; Codehighlighter1_401_556_Open_Text.style.display='none'; Codehighlighter1_401_556_Closed_Image.style.display='inline'; Codehighlighter1_401_556_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_401_556_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_401_556_Closed_Text.style.display='none'; Codehighlighter1_401_556_Open_Image.style.display='inline'; Codehighlighter1_401_556_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span id=Codehighlighter1_401_556_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_401_556_Open_Text><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;no&nbsp;transition&nbsp;name</span><span style="COLOR: #008000"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;size&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(&nbsp;parent.getChildren()</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">?</span><span style="COLOR: #000000">&nbsp;parent.getChildren().size()</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;:&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">&nbsp;);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tokenName&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Integer.toString(size);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;tokenName;&nbsp;</span></div>
<p style="FONT-SIZE: 12pt"><br><br>这里"token"那里来？这个token名字，你自己可以根据命名规则得到 。看到这里应该很明了了 <br><br>token的命名规则；首先根据transitionName的名字命名，这个transitionName的名字是你自己的写的你不可能不知道。 如果transitionName的名字重名了，加自然数区分 当然，如果transitionName没有名字，用分支的个数+1作为名字。 <br><br>应该比较清楚了。 <br><br>PS：这个是qq聊天记录的整理版，所以说话比较诡异。为的是记录下来避免忘记，也感谢群里的朋友。发现互相解决问题是提高水平的一个捷径。。</p>
<img src ="http://www.blogjava.net/sshwsfc/aggbug/113217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2007-04-24 16:04 <a href="http://www.blogjava.net/sshwsfc/archive/2007/04/24/113217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>说说Rails吧，config的幕后工作</title><link>http://www.blogjava.net/sshwsfc/archive/2006/11/21/82487.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Tue, 21 Nov 2006 04:10:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2006/11/21/82487.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/82487.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2006/11/21/82487.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/82487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/82487.html</trackback:ping><description><![CDATA[
		<p>说ruby是怪异的语法有点不妥当，动态语言里面不乏这样的语法出现。但是看了一些源码后发现，使用ruby的用法真的各有不同，就像大家以前说的，ruby每个人写出来的可能都不同。</p>
		<p>现来说Rails里面如何加载config的吧。</p>
		<p>在java里面config绝对是一个resource文件，然后通过读取配置的工具加入进来，在分析处理。</p>
		<p>在ROR里面完全不是这么回事。</p>
		<p>1.首先大家要了解的是，在我们启动 ruby script/server 的时候，rails做了一系列的处理，最后他执行了<font face="Arial">environment.rb</font></p>
		<div class="code_title">
				<em>
						<font color="#990033">ruby 代码</font>
				</em>
				<br />
		</div>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">Rails::Initializer.run do </span>
				<span style="COLOR: #000000">|</span>
				<span style="COLOR: #000000">config</span>
				<span style="COLOR: #000000">|</span>
				<span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> 这里能插入我们自己的配置。    </span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">  </span>
				<span style="COLOR: #008000">#</span>
				<span style="COLOR: #008000"> config. 之类    </span>
				<span style="COLOR: #008000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</span>
				<span style="COLOR: #000000">end   </span>
		</div>
		<p class="alt">这里的config其实是Initializer内部的一个变量，掌控全局的配置信息，我们可以使用这个config来配置我们想要的。<span><span>Rails::Initializer.run的源码是这样的，yield再一次显示了他的威力，让我们在配置文件中得以配置config。然后实例化了一个initializer 之后，把config作为参数传入了。</span></span></p>
		<div class="code_title">
				<em>
						<font color="#990033">ruby 代码</font>
				</em>
				<br />
		</div>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">def</span>
				<span style="COLOR: #000000"> self.run(command </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> :process, configuration </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> Configuration.new)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
				<span style="COLOR: #0000ff">yield</span>
				<span style="COLOR: #000000"> configuration </span>
				<span style="COLOR: #0000ff">if</span>
				<span style="COLOR: #000000"> block_given?    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  initializer </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> new configuration    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  initializer.send(command)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  initializer    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end   </span>
		</div>
		<p class="alt">我们接着往下走，可以看到initializer 做了一系列的初始化工作，包括load_path的设定，路由的初始化，和activerecord的初始化。我们关心的还是配置如何起作用，那么来看看<font face="Arial">environments目录下面的配置文件是如何导入的吧。</font></p>
		<div class="code_title">
				<em>
						<font color="#990033">ruby 代码</font>
				</em>
		</div>
		<div class="dp-highlighter">
				<div class="bar">
				</div>
		</div>
		<p>
				<span class="builtin">
				</span>
		</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #0000ff">def</span>
				<span style="COLOR: #000000"> load_environment    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  silence_warnings do   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    config </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> configuration    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    constants </span>
				<span style="COLOR: #000000">=</span>
				<span style="COLOR: #000000"> self.</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">.constants    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    eval(IO.read(configuration.environment_path), binding)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    (self.</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">.constants </span>
				<span style="COLOR: #000000">-</span>
				<span style="COLOR: #000000"> constants).each do </span>
				<span style="COLOR: #000000">|</span>
				<span style="COLOR: #000000">const</span>
				<span style="COLOR: #000000">|</span>
				<span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      Object.const_set(const, self.</span>
				<span style="COLOR: #0000ff">class</span>
				<span style="COLOR: #000000">.const_get(const))    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
		</div>
		<p>IO<span>.read(configuration.environment_path) ，，这里就不使用什么回调不回调了，而是干脆IO拿出来eval一把，这里也是吃了一惊，这样也可以呀~~~~~~~然后，我们可以看看，他处理常量的方法，把自己配置文件中的常量全部放入Object里面，起到全局常量的目的。</span></p>
		<p>
				<span>最绝的还是<font face="Arial">initialize_framework_settings，使用了有一个ruby的技巧。</font></span>
		</p>
		<span>
				<div class="code_title">
						<em>
								<font color="#990033">ruby 代码</font>
						</em>
				</div>
				<div class="bar">
				</div>
				<p class="alt">
				</p>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">def</span>
						<span style="COLOR: #000000"> initialize_framework_settings    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  configuration.frameworks.each do </span>
						<span style="COLOR: #000000">|</span>
						<span style="COLOR: #000000">framework</span>
						<span style="COLOR: #000000">|</span>
						<span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    base_class </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> framework.to_s.camelize.constantize.const_get(</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #800000">Base</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #000000">)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    configuration.send(framework).each do </span>
						<span style="COLOR: #000000">|</span>
						<span style="COLOR: #000000">setting, value</span>
						<span style="COLOR: #000000">|</span>
						<span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      base_class.send(</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #800000">#{setting}=</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #000000">, value)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end   </span>
				</div>
				<p>configuration.frameworks里面存放的是rails个个组件的名字，比方说active_record之类。然后把这个名字大写转换，然后用constantize取得ActiveRecord这个Module(注意，这些东西都在activesupport里面呢，activesupport/lib/active_support/core_ext/string/inflections.rb )。然后用const_get取得这个模块的Base类，也就是ActiveRecord::Base这个类了（下面都叫做Base类），所有的Rails的组件都是这个命名规则改天我们自己想要做一个Rails的组件加进来，也可以这样（但是要稍微修改一个源码）。</p>
				<p>然后，我们吧config里面的内容给Base类。configuration.send(framework)是调用一个组件名称的方法，比方说active_record，就是去的config里面的active_record属性（这是最基本的），通过后面的do我们可以看到config返回的是一个hash，然后把hash中每一个key作为变量，value为传入值，传入Base类。。。这里大家应该没什么问题了，看看我们的config文件是怎么写的吧。</p>
				<div class="code_title">
						<em>
								<font color="#990033">ruby 代码</font>
						</em>
						<br />
				</div>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> Settings specified here will take precedence over those in config/environment.rb    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> In the development environment your application's code is reloaded on    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#</span>
						<span style="COLOR: #008000"> every request.  This slows down response time but is perfect for development    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#</span>
						<span style="COLOR: #008000"> since you don't have to restart the webserver when you make code changes.    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">config.cache_classes </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> false   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> Log error messages when you accidentally call methods on nil.    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">config.whiny_nils </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> true   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> Enable the breakpoint server that script/breakpointer connects to    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">config.breakpoint_server </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> true   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> Show full error reports and disable caching    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">config.action_controller.consider_all_requests_local </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> true   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />config.action_controller.perform_caching             </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> false   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />config.action_view.cache_template_extensions         </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> false   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />config.action_view.debug_rjs                         </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> true   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						<span style="COLOR: #008000">#</span>
						<span style="COLOR: #008000"> Don't care if the mailer can't send    </span>
						<span style="COLOR: #008000">
								<br />
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</span>
						<span style="COLOR: #000000">config.action_mailer.raise_delivery_errors </span>
						<span style="COLOR: #000000">=</span>
						<span style="COLOR: #000000"> false   </span>
				</div>
				<p class="alt">哦，看着很晕吧，config就是我们的配置对象，按照我们上面的说法，config.action_view之类framework的变量应该是一个hash才对呀，如果是hash的话，不应该用这样的方式传入，可能会用 config.action_view = {:debug_rjs =&gt; true}来传入。</p>
				<p>OK.我们来看这个变量到底是什么样的hash。</p>
				<div class="code_title">
						<em>
								<font color="#990033">ruby 代码</font>
						</em>
				</div>
				<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						<span style="COLOR: #0000ff">def</span>
						<span style="COLOR: #000000"> initialize    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  <img src="http://www.blogjava.net/images/dot.gif" />.    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  <img src="http://www.blogjava.net/images/dot.gif" />.    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
						<span style="COLOR: #0000ff">for</span>
						<span style="COLOR: #000000"> framework </span>
						<span style="COLOR: #0000ff">in</span>
						<span style="COLOR: #000000"> default_frameworks    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    self.send(</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #800000">#{framework}=</span>
						<span style="COLOR: #800000">"</span>
						<span style="COLOR: #000000">, OrderedOptions.new)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end   </span>
				</div>
				<p class="alt">在初始化这些变量的时候，Rails给他赋值为OrderedOptions.<span class="keyword">new。这个特殊的类型可能就是关键。</span></p>
				<span class="keyword">
						<div class="code_title">
								<em>
										<font color="#990033">ruby 代码</font>
								</em>
								<br />
						</div>
						<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								<span style="COLOR: #0000ff">class</span>
								<span style="COLOR: #000000"> OrderedOptions </span>
								<span style="COLOR: #000000">&lt;</span>
								<span style="COLOR: #000000"> OrderedHash </span>
								<span style="COLOR: #008000">#</span>
								<span style="COLOR: #008000">:nodoc:    </span>
								<span style="COLOR: #008000">
										<br />
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
								</span>
								<span style="COLOR: #000000">  </span>
								<span style="COLOR: #0000ff">def</span>
								<span style="COLOR: #000000"> []</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">(key, value)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    super(key.to_sym, value)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
								<span style="COLOR: #0000ff">def</span>
								<span style="COLOR: #000000"> [](key)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    super(key.to_sym)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span>
								<span style="COLOR: #0000ff">def</span>
								<span style="COLOR: #000000"> method_missing(name, </span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">args)    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">if</span>
								<span style="COLOR: #000000"> name.to_s </span>
								<span style="COLOR: #000000">=~</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">/</span>
								<span style="COLOR: #000000">(.</span>
								<span style="COLOR: #000000">*</span>
								<span style="COLOR: #000000">)</span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000">$</span>
								<span style="COLOR: #000000">/</span>
								<span style="COLOR: #000000">    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      self[$</span>
								<span style="COLOR: #000000">1</span>
								<span style="COLOR: #000000">.to_sym] </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> args.first    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span>
								<span style="COLOR: #0000ff">else</span>
								<span style="COLOR: #000000">   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      self[name]    <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end   <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end   </span>
						</div>
						<p class="alt">看到其中的玄妙了么，method_missing~~~！！ 如果调用一个**=的方法 ，就像当用传入一个HASH的值，key就是方法的名字。</p>
						<p>也就是：<span>config.action_view.debug_rjs  = </span><span class="keyword">true</span><span> 相当于<span>config.action_view[:debug_rjs] = true</span></span></p>
						<p>
								<span>
										<span>OK ，大体上描述了一下，可以看到简单的一个Rails初始化已经给我们展示了几乎全部ruby的靓丽之处，这能说明，这个亮点肯定是贯穿rails的基本，在以后的深入研究中我们就能看到了。</span>
								</span>
						</p>
				</span>
		</span>
<img src ="http://www.blogjava.net/sshwsfc/aggbug/82487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2006-11-21 12:10 <a href="http://www.blogjava.net/sshwsfc/archive/2006/11/21/82487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>说说Rails吧，启动开始。</title><link>http://www.blogjava.net/sshwsfc/archive/2006/11/20/82401.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Mon, 20 Nov 2006 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2006/11/20/82401.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/82401.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2006/11/20/82401.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/82401.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/82401.html</trackback:ping><description><![CDATA[
		<p>为了记录自己看Rails源码的过程，全程记录无废话。<br /><br />我们看看script/server都干了什么</p>
		<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee">
				<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				<span style="COLOR: #000000">require File.dirname(__FILE__) </span>
				<span style="COLOR: #000000">+</span>
				<span style="COLOR: #000000"> </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">/../config/boot</span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">
						<br />
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require </span>
				<span style="COLOR: #000000">'</span>
				<span style="COLOR: #000000">commands/server</span>
				<span style="COLOR: #000000">'</span>
		</div>
		<br />引用了boot.rb这个文件。看来这个文件是rails启动的入口，来看看怎么回事吧。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">unless defined?(RAILS_ROOT)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  root_path </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> File.join(File.dirname(</span><span style="COLOR: #800080">__FILE__</span><span style="COLOR: #000000">), </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">..</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  unless RUBY_PLATFORM </span><span style="COLOR: #000000">=~</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mswin32</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">pathname</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    root_path </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> Pathname.new(root_path).cleanpath(true).to_s<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  RAILS_ROOT </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> root_path<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end</span></div>这一部分定义了RAILS_ROOT这个系统的全局变量，指定了项目的根目录，大家可以在以后华丽的使用了。<br /><br />下一部分是找到rails，粗略看一下。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> File.directory?(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">#{RAILS_ROOT}/vendor/rails</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    require </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">#{RAILS_ROOT}/vendor/rails/railties/lib/initializer</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">rubygems</span><span style="COLOR: #800000">'</span></div>这里能看到，他先跑到<font color="#800000">vendor/rails<font color="#000000">去找rails了，这就是我们为什么能在插件里用rails是原因。如果没有那么gems的干活。<br />接下来是初始化一下load_path，没什么看的了。boot.rb就这样的吧。<br /><br />回到script/server的第二行，包含了<span style="COLOR: #000000">'</span><span style="COLOR: #000000">commands/server</span><span style="COLOR: #000000">'这个文件，这个文件是什么？Rails的源码里面找吧。我们在Rails的源码里面找到这个文件。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">active_support</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">fileutils</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />begin<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  require_library_or_gem </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">fcgi</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />rescue Exception<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #008000">#</span><span style="COLOR: #008000"> FCGI not available</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />server </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> case ARGV.first<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  when </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">lighttpd</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    ARGV.shift<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  when </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">webrick</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    ARGV.shift<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> RUBY_PLATFORM !</span><span style="COLOR: #000000">~</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">mswin</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> !silence_stderr { `lighttpd </span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">version` }.blank? </span><span style="COLOR: #000000">&amp;&amp;</span><span style="COLOR: #000000"> defined?(FCGI)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">lighttpd</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">webrick</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />    end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> server </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">webrick</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  puts </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">=&gt; Booting WEBrick<img src="http://www.blogjava.net/images/dot.gif" /></span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  puts </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">=&gt; Booting lighttpd (use 'script/server webrick' to force WEBrick)</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />FileUtils.mkdir_p(</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">w( tmp</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">sessions tmp</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">cache tmp</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">sockets ))<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">commands/servers/#{server}</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div></span></font></font>没想到ActiveRecord居然是在这里引用的，这个ActiveRecord里面扩展了很对Ruby的既有类型，所以我们看源码的时候如果发现有不熟悉的方法，就来这里找找，当然，看Rails的API是最好的选择。<br /><br />从参数一目了然，我们可以传入server的名字，<span style="COLOR: #800000">lighttpd和<span style="COLOR: #800000">webrick<font color="#000000">，根据不同的server选择不同的server文件来读取。我们还是看看<span style="COLOR: #800000">webrick<font color="#000000">的吧。<br /><br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">webrick</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">optparse</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />OPTIONS </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> {<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :port            </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">3000</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :ip              </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">0.0.0.0</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :environment     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> (ENV[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">RAILS_ENV</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">development</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">).dup,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :server_root     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> File.expand_path(RAILS_ROOT </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">/public/</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">),<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :server_type     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> WEBrick::SimpleServer,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :charset         </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">UTF-8</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :mime_types      </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> WEBrick::HTTPUtils::DefaultMimeTypes<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />}<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />ARGV.options do </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">opts</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  script_name </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> File.basename($0)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.banner </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Usage: ruby #{script_name} [options]</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.separator </span><span style="COLOR: #800000">""</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-p</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--port=port</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, Integer,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Runs Rails on the specified port.</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Default: 3000</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">v</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> OPTIONS[:port] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-b</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--binding=ip</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, String,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Binds Rails to the specified ip.</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Default: 0.0.0.0</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">v</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> OPTIONS[:ip] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-e</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--environment=name</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, String,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Specifies the environment to run this server under (test/development/production).</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Default: development</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">v</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> OPTIONS[:environment] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-m</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--mime-types=filename</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, String,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                  </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Specifies an Apache style mime.types configuration file to be used for mime types</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />                  </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Default: none</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">mime_types_file</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> OPTIONS[:mime_types] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WEBrick::HTTPUtils::load_mime_types(mime_types_file) }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-d</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--daemon</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Make Rails run as a Daemon (only works if fork is available -- meaning on *nix).</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          ) { OPTIONS[:server_type] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> WEBrick::Daemon }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-c</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--charset=charset</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, String,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Set default charset for output.</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Default: UTF-8</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { </span><span style="COLOR: #000000">|</span><span style="COLOR: #000000">v</span><span style="COLOR: #000000">|</span><span style="COLOR: #000000"> OPTIONS[:charset] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.separator </span><span style="COLOR: #800000">""</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.on(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">-h</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--help</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Show this help message.</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">) { puts opts; exit }<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  opts.parse!<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />end<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />ENV[</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">RAILS_ENV</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> OPTIONS[:environment]<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />RAILS_ENV.replace(OPTIONS[:environment]) </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> defined?(RAILS_ENV)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require RAILS_ROOT </span><span style="COLOR: #000000">+</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">/config/environment</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />require </span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">webrick_server</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />OPTIONS[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">working_directory</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> File.expand_path(RAILS_ROOT)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />puts </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">=&gt; Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />puts </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">=&gt; Ctrl-C to shutdown server; call with --help for options</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> OPTIONS[:server_type] </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> WEBrick::SimpleServer<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />DispatchServlet.dispatch(OPTIONS)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div></font></span></font></span></span>本来不想把大段的代码贴上来，但是这里面的内容可能大家都比较关心，涉及到server的启动参数。<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :port            <span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">端口</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :ip              </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> server ip</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :environment     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000">运行环境</span><span style="COLOR: #000000">,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :server_root     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> web访问的目录，（很多人问这个怎么改）</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :server_type     </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> WEBrick::SimpleServer,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :charset         </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> </span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">UTF-8</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">, 编码<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />  :mime_types      </span><span style="COLOR: #000000">=&gt;</span><span style="COLOR: #000000"> WEBrick::HTTPUtils::DefaultMimeTypes<br /><br />后面的require 引入了两个文件，一个是<span style="COLOR: #800000">'</span><span style="COLOR: #800000">webrick_server</span><span style="COLOR: #800000">'<font color="#000000">，别看，就是他。另外一个是</font><font color="#800000">config/environment</font><font color="#000000">，这个文件是系统的全局配置文件，很重要，我们还是下次看看这个文件去吧。里面还真挺有意思。<br /><br />（不知道blogjava让不让写ROR的文章，看到有人写了所以放在首页了，如果不妥，我会尽快删除）</font></span></span><img src ="http://www.blogjava.net/sshwsfc/aggbug/82401.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2006-11-20 23:43 <a href="http://www.blogjava.net/sshwsfc/archive/2006/11/20/82401.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>秀逗的JBPM</title><link>http://www.blogjava.net/sshwsfc/archive/2006/08/24/65446.html</link><dc:creator>差沙</dc:creator><author>差沙</author><pubDate>Thu, 24 Aug 2006 03:07:00 GMT</pubDate><guid>http://www.blogjava.net/sshwsfc/archive/2006/08/24/65446.html</guid><wfw:comment>http://www.blogjava.net/sshwsfc/comments/65446.html</wfw:comment><comments>http://www.blogjava.net/sshwsfc/archive/2006/08/24/65446.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.blogjava.net/sshwsfc/comments/commentRss/65446.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sshwsfc/services/trackbacks/65446.html</trackback:ping><description><![CDATA[这两天找点时间看了看jbpm，其设计思想相当不错，功能强劲，而且几乎实现了工作流模型的所有要求。可扩展的思想也是贯穿了整个jbpm的设计思路，这都是能看得出来的优势。但是这也仅仅是限于表面的一两眼，如果真的研究起其代码来，你会惊讶的发现Jbpm的代码漏洞百出，其设计思想完全没有发挥出来，应该说，Jbpm的代码真是“秀逗”了。下面来举几个例子吧。另外，我还没有看svn上的最新代码，所以可能有的问题jbpm自己已经修复，那就谢天谢地了。下面的代码基于jbpm3.1<br /><br /><strong>秀逗1。无中生有</strong><br /><br />看到最核心的JpdlXmlReader代码真实欲哭无泪，如果好好精简精简，至少能踢掉1/3的代码。而其中甚至有些无中生有的代码：<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> ( (actorId</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">)<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />           </span><span style="COLOR: #000000">||</span><span style="COLOR: #000000"> (pooledActors</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) <br /><img id="Codehighlighter1_68_272_Open_Image" onclick="this.style.display='none'; Codehighlighter1_68_272_Open_Text.style.display='none'; Codehighlighter1_68_272_Closed_Image.style.display='inline'; Codehighlighter1_68_272_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_68_272_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_68_272_Closed_Text.style.display='none'; Codehighlighter1_68_272_Open_Image.style.display='inline'; Codehighlighter1_68_272_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />         ) </span><span id="Codehighlighter1_68_272_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_68_272_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assignmentDelegation.setProcessDefinition(processDefinition);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assignmentDelegation.setClassName(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.jbpm.taskmgmt.assignment.ActorAssignmentHandler</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        String configuration </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">""</span><span style="COLOR: #000000">;</span></span></div>我们看到，如果符合之前的条件，就用代理类来代理<span style="COLOR: #000000">org.jbpm.taskmgmt.assignment.ActorAssignmentHandler这个类，但是找了好半天也没有找到这个类。。。。 难道是让用户在自己的项目中用这个类么？还是为了兼容原来的程序，，就算是其中一种，但是，可但是，这个条件根本就不可能满足，也就是说这是段废话，而且还无中生有的出来个ActorAssignmentHandler。。<br /><br /><strong>秀逗2。画蛇添足</strong><br /><br />应该是我的基本功不都扎实，实在是高不明白下面的代码在干什么。。。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_41_342_Open_Image" onclick="this.style.display='none'; Codehighlighter1_41_342_Open_Text.style.display='none'; Codehighlighter1_41_342_Closed_Image.style.display='inline'; Codehighlighter1_41_342_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_41_342_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_41_342_Closed_Text.style.display='none'; Codehighlighter1_41_342_Open_Image.style.display='inline'; Codehighlighter1_41_342_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #000000">  </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> setActorId(String actorId) </span><span id="Codehighlighter1_41_342_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_41_342_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    DefaultAuthenticationService authenticationService </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (DefaultAuthenticationService) services.getAuthenticationService();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    DefaultAuthenticationService defaultAuthenticationService </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (DefaultAuthenticationService) authenticationService;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    defaultAuthenticationService.setActorId(actorId);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />  }</span></span></div></span>先强制转换成DefaultAuthenticationService，然后再强制转换成DefaultAuthenticationService。。。。<br />而且这里这么设计基本上就把DefaultAuthenticationService实现的AuthenticationService接口晾在那里了，根本就是应该用AuthenticationService这个接口来说话才对。jbpm的service设计的扩展性很强，可自己配制。但如果这么用service的话，再怎么扩展也没用。<br /><br /><strong>秀逗3。莫“名”其妙</strong><br /><br />Jbpm中变量的名字真的莫名其妙，很多明明是Map的类型他叫xxList，而不是Map的类型，他却叫xxMap。这个地方我相信应该是能体现出程序员编写程序的严谨性的地方，而Jbpm作的还不够好。<br /><br /><strong>秀逗4。固若金汤</strong><br /><br />Jbpm的扩展性贯穿始终，但是在最重要的泳道的扩展上却小家子气起来。看看泳道类代理的扩展代码。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Codehighlighter1_21_297_Open_Image" onclick="this.style.display='none'; Codehighlighter1_21_297_Open_Text.style.display='none'; Codehighlighter1_21_297_Closed_Image.style.display='inline'; Codehighlighter1_21_297_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_21_297_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_21_297_Closed_Text.style.display='none'; Codehighlighter1_21_297_Open_Image.style.display='inline'; Codehighlighter1_21_297_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (expression</span><span style="COLOR: #000000">!=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">)</span><span id="Codehighlighter1_21_297_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_21_297_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assignmentDelegation.setProcessDefinition(processDefinition);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assignmentDelegation.setClassName(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">org.jbpm.identity.assignment.ExpressionAssignmentHandler</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        assignmentDelegation.setConfiguration(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;expression&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">expression</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">&lt;/expression&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />      <br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />    }</span></span></div>写的很明确，如果泳道使用表达式来表示的那么就用代理类来代理处理表达式。。我本想，太好了，写我自己的表达式，然后代理交给Acegi来根据表达式分配ActorId，但是，可是，但可是。他的代理类居然是写死的，写得就是自己的java.identity包里面的东西，不是说java.identity设计的不好，但是一个综合系统的用户角色管理系统是不可能跟着你的jbpm走的。强行要加入的java.identity的设计有点保护自我的意思，真的固若金汤，让我结合acegi的想法又是难上加难。（不过还是有办法的。大家自己找找看）。<br /><br /><strong>秀逗5。口径不一</strong><br /><br />口径不一就是指两个程序部分的结合不一致。这种例子很多，我举一个程序和xsd的冲突的例子。<br />Instantiator是jbpm代理里面一个比较不错的概念。代理功能之一是生成代理的类的实例，而Instantiator则是负责生成实例的机制，这个Instantiator设计的不错，可以在配制文件中的config-type属性来扩展。看程序。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">      </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> find the instantiator</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">      instantiator </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (Instantiator) instantiatorCache.get(configType);<br /><img id="Codehighlighter1_134_447_Open_Image" onclick="this.style.display='none'; Codehighlighter1_134_447_Open_Text.style.display='none'; Codehighlighter1_134_447_Closed_Image.style.display='inline'; Codehighlighter1_134_447_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_134_447_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_134_447_Closed_Text.style.display='none'; Codehighlighter1_134_447_Open_Image.style.display='inline'; Codehighlighter1_134_447_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />      </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (instantiator </span><span style="COLOR: #000000">==</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_134_447_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_134_447_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> load the instantiator class</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        Class instantiatorClass </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> classLoader.loadClass(configType);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> instantiate the instantiator with the default constructor</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">        instantiator </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> (Instantiator) instantiatorClass.newInstance();<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        instantiatorCache.put(configType, instantiator);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />      }</span></span></div>这里的设计很人性化，可以根据configType来用自己的构造器，但是xsd却不这么想。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">      </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:attribute </span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="config-type"</span><span style="COLOR: #ff0000"> default</span><span style="COLOR: #0000ff">="field"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:simpleType</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:restriction </span><span style="COLOR: #ff0000">base</span><span style="COLOR: #0000ff">="xs:string"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:enumeration </span><span style="COLOR: #ff0000">value</span><span style="COLOR: #0000ff">="field"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:enumeration </span><span style="COLOR: #ff0000">value</span><span style="COLOR: #0000ff">="bean"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:enumeration </span><span style="COLOR: #ff0000">value</span><span style="COLOR: #0000ff">="constructor"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />            </span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">xs:enumeration </span><span style="COLOR: #ff0000">value</span><span style="COLOR: #0000ff">="configuration-property"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />          </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">xs:restriction</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">xs:simpleType</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />      </span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">xs:attribute</span><span style="COLOR: #0000ff">&gt;</span></div>可以看到它限制了4种类型，别说使用自己的构造器了，就连他自己的XmlInstantiator都不再考虑范围之内，真是大义灭亲呀。。<br /><br />构造器来这里的作用很大，我写了自己的spring构造器，构造的时候使用beanFactory来构造，这样就算是存在数据库里面的class也能当作spring的bean来处理。但是如果用xsd的话就会导致交验错误，所以索性把xsd去掉了，还好一切正常，就是感觉别扭点。<br /><br />秀逗N。。。 能够看得出来Jbpm需要提高的地方还很多。但是这些问题应该是一些开发人员的小疏忽，相信在以后的版本中可以改进。不管再怎么秀逗，Jbpm在工作流中仍然保有着强劲的地位，对BPM模型的实现也作的最为全面。而jbpm的par热部署和IDE也是整个系统中的两大亮点，这些优点都是不可不提的，所以我仍旧支持Jbpm，希望他能更加迅速的发展壮大起来。。。。<br /><br />PS：文中错误之处还望大家指出，我希望有些“秀逗”是我自己秀逗了。<img src ="http://www.blogjava.net/sshwsfc/aggbug/65446.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sshwsfc/" target="_blank">差沙</a> 2006-08-24 11:07 <a href="http://www.blogjava.net/sshwsfc/archive/2006/08/24/65446.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>