咖啡's profileSeparate LivesPhotosBlogLists Tools Help

Blog


    13/08/2009

    Using the ProxyFactoryBean to create AOP proxies

    Using the ProxyFactoryBean to create AOP proxies
    If you're using the Spring Ioc container (an applicationContext or BeanFactory) for you business object--and you should be!-- you will want to use one of Spring's AOP fatoryBeans.(Remeber that a factory bean introduces a layer of indirection, enabling it to create objects of different type).

    The basic way to create an AOP proxy in Spring to use the org.springframework.aop.framework.ProxyFactoryBean. This gives complete control over the pointcuts an advice that will apply, and theire ordering . However ,there are simpler options that are preferable(更可取的、更好的) if you don't need such control.

    Basics
    The proxyFactoryBean,like other Spring FactoryBean implementations,introduces a level of indirection(间接). If you define a ProxyFactoryBean with name foo,what objects referencing foo see is not the ProxyFactoryBean instance itself, but an object created by the ProxyFactoryBeans's implementation of the getObject() method. This method will create an AOP proxy wrapping a target object.

    One of the most important benefits of using a ProxyFactoryBean or other IoC-aware to create AOP proxies, it that it means that advices and pointcuts can also be managed by IoC. This is a powerful feature , enabling certain approaches that are hard to achieve with other AOP frameworks. For example,an advice may itself reference application objects(besides the target , which should be available in any AOP framework),benefiting from all the pluggability provided by Dependency Injection.

    JavaBean properties
    Like most FactoryBean implementations provided with Spring, ProxyfactoryBean is itself a JavaBean. It properties are used to:
    Specify the target you  want to proxy
    Specify whether to use CGLIB

    Some key properties are inherited from org.springframework.aop.framework.ProxyConfig: the subclass for all AOP proxy factories. These include:
    proxyTargetClass: true if we should proxy the target class,rather than its interfaces. If this  is true we need to use CGLIB.

    optimize: whether to apply aggressive optimization to created proxies. Don't use this setting unless you  understand how the relevant(相关的) AOP proxy handles optimization. This is currently used only for CGLIB proxies;it has no effect with  JDK dynamic proxies(the default).

    frozen:whether avice changes should be disallowed once the proxy factory has bean configured. Default is false.

    exposeProxy: whether the current proxy should be exposed in a ThreadLocal so that it can be accessed by the target (It's available via the MethodInvocation without the need for a ThreadLocal) If a target needs to obtain the proxy and exposedProxy is true, the target can use the AopContext.currentProxy() method.

    aopProxyFactory: the implementation of AopProxyFactory to use. Offers a way of customizing whether to use dynammic proxies,CGLIB or any other proxy strategy. The default implementation will choose dynamic proxies or CGLIB appropriately. There should be need to use this property, it's intended to allow the addition of new proxy types in spring 1.1.

    Other properties specific to ProxyFactoryBean include:
    .proxyInterfaces: array of String interface names.  If this isn't supplied, a CGLIB proxy for the target class will be used.
    .interceptorNames:String array of Advisor,interceptor or other advice names to apply.Ordering is sugnicicant. first come,first serve that is. The first interceptor in the list will be the first to be able to interceptor the invocation (of course if it concerns a regular MethodInterceptor or BeforeAdvice. The names are bean names in the current factory , including  bean names from ancestor factories. You  can't mention bean references here since doing so would result iin the ProxyFactoryBean ignoring the singleton  setting of the advise. you can append an iinterceptor name with an asterisk(*).  This will result  in the application of all advisor beans withe names starting with the part before the asterisk to be applied.  An example of using this feature can be found below.

    Singleton: whether or not the factory should return a single object, no matter how often the getObject() method is called. Server FactoryBean implementations offer such a method. Default value is true. If you want to use stateful advice --for example ,for stateful mixins-user prototype advices along withe s singleton value of false.

    Proxying interfaces

    <bean id="personTarget" class="com.mycompany.PersionImpl">
       <property name="name"><value>Tony</value></property>
       <property name="age"><value>51</value></property>  
    </bean>

    <bean id="myAdvisor" class="com.mycompany.MyAdvisor">
       <property name="someProperty"><value>Custom string property value</value></property>
    </bean>

    <bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInteceptor" ></bean>

    <bean id="person" class="org.springframework.aop.framework.ProxyFactoryBean">
       <property name="proxyInterface"><value>com.company.Person</value></property>
      
       <property name="target"><ref local="personTarget"/></property>
       <property name="interceptorNames">
          <list>
             <value>myAdvisor</value>
             <value>debugInterceptor</value>
          </list>
       </property>
    </bean>

    23/08/2007

    exjs and dwr and spring

    ExtJs 在Web UI已经获得很大的殊荣,但单凭借它 Client UI 还无法霸占BS 那么丰富的应用。。他还要选择 一个Web层与后台一起来交互完成一个完美的系统。

    Extjs的天生丽质的, 完美了融合JQuery,Prototype,YUI, 和她结合当然也需要出类拔萃,生出名门。 如果采用Java为开发主语言,那么 ExtJS + DWR + SPRING 算是门当户对。

    可惜Extjs 的DataStore 的 prxy 并没有DWR一席,因为DWR返回的是Java对象与JSON非常像, 然而DWR 的在于它与Web远程Java方法的直接会话,因此有着非常灵活的一面。所以,有时候使用DWR对于J2EE来说,要更好于JSON,他做了JSON做不到事.

    extjs官方论坛里已经有人编写了这样的扩展,后经人丰富,现在基本能满足要求了。
    DWR扩展代码如下,创建 Ext.data.DWRProxy类。同样也继承Ext.data.DataProxy ,拿来show着解读一下。

    dwr.js

    Ext.data.DWRProxy = function(dwrCall, pagingAndSort){
    Ext.data.DWRProxy.superclass.constructor.call(this);
    this.dwrCall = dwrCall;
    //this.args = args;
    this.pagingAndSort = (pagingAndSort!=undefined ? pagingAndSort : true);
    };

    Ext.extend(Ext.data.DWRProxy, Ext.data.DataProxy, {
    load : function(params, reader, callback, scope, arg) {
    if(this.fireEvent("beforeload", this, params) !== false) {
    var sort;
    if(params.sort && params.dir) sort = params.sort + ' ' + params.dir;
    else sort = '';
    var delegate = this.loadResponse.createDelegate(this, [reader, callback, scope, arg], 1);
    var callParams = new Array();
    if(arg.arg) {
    callParams = arg.arg.slice();
    }

    if(this.pagingAndSort) {
    callParams.push(params.start);
    callParams.push(params.limit);
    callParams.push(sort);
    }

    callParams.push(delegate);
    this.dwrCall.apply(this, callParams);
    } else {
    callback.call(scope || this, null, arg, false);
    }
    },

    loadResponse : function(listRange, reader, callback, scope, arg) {
    var result;
    try {
    result = reader.read(listRange);
    } catch(e) {
    this.fireEvent("loadexception", this, null, response, e);
    callback.call(scope, null, arg, false);
    return;
    }
    callback.call(scope, result, arg, true);
    },

    update : function(dataSet){},

    updateResponse : function(dataSet)
    {}
    });

    Ext.data.ListRangeReader = function(meta, recordType){
    Ext.data.ListRangeReader.superclass.constructor.call(this, meta, recordType);
    this.recordType = recordType;
    };
    Ext.extend(Ext.data.ListRangeReader, Ext.data.DataReader, {
    getJsonAccessor: function(){
    var re = /[\[\.]/;
    return function(expr) {
    try {
    return(re.test(expr))
    ? new Function("obj", "return obj." + expr)
    : function(obj){
    return obj[expr];
    };
    } catch(e){}
    return Ext.emptyFn;
    };
    }(),

    read : function(o){
    var recordType = this.recordType, fields = recordType.prototype.fields;

    //Generate extraction functions for the totalProperty, the root, the id, and for each field
    if (!this.ef) {
    if(this.meta.totalProperty) {
    this.getTotal = this.getJsonAccessor(this.meta.totalProperty);
    }

    if(this.meta.successProperty) {
    this.getSuccess = this.getJsonAccessor(this.meta.successProperty);
    }

    if (this.meta.id) {
    var g = this.getJsonAccessor(this.meta.id);
    this.getId = function(rec) {
    var r = g(rec);
    return (r === undefined || r === "") ? null : r;
    };
    } else {
    this.getId = function(){return null;};
    }
    this.ef = [];
    for(var i = 0; i < fields.length; i++){
    f = fields.items[i];
    var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
    this.ef[i] = this.getJsonAccessor(map);
    }
    }

    var records = [];
    var root = o.data, c = root.length, totalRecords = c, success = true;

    if(this.meta.totalProperty){
    var v = parseInt(this.getTotal(o), 10);
    if(!isNaN(v)){
    totalRecords = v;
    }
    }

    if(this.meta.successProperty){
    var v = this.getSuccess(o);
    if(v === false || v === 'false'){
    success = false;
    }
    }

    for(var i = 0; i < c; i++){
    var n = root[i];
    var values = {};
    var id = this.getId(n);
    for(var j = 0; j < fields.length; j++){
    f = fields.items[j];
    var v = this.ef[j](n);
    values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
    }
    var record = new recordType(values, id);
    records[i] = record;
    }

    return {
    success : success,
    records : records,
    totalRecords : totalRecords
    };
    }
    });



    经过改造之后,那么DWR可以像JSON一样,返回的数据作为DataStore
    代码片断

    ds = new Ext.data.Store({
    proxy: new Ext.data.DWRProxy(TodoService.getItems, true), //TotoService.getItems dwr开放出来的Java获取数据方法
    reader: new Ext.data.ListRangeReader(
    {id:'id', totalProperty:'totalSize'}, recordType),
    remoteSort: true
    });



    Spring实现了强大的管理了后台的JavaBean,干干净净的注入创建了每个对象, DWR天生又是支持Spring,无缝的讲Spring的后台Bean 发布到Web层作为JavaScript对象,和JavaScript方法。中途不需要人工干预写Servlet.


    不多说了, 跑了下代码,通过! 
    22/09/2005

    今天你Power Toys了吗?

    Power Toys是MSN Spaces刚刚推出的一组允许用户对自己的Spaces进行更多自定义设置的功能,目前包括Windows Media Player Power Toy Tweak UI Power Toy
    (Via The Space Craft )

    Windows Media Player Power Toy:添加可以在线播放网络音频/视频文件的Media Player模块。支持多种文件类型,可以设置开始位置、重复次数、播放速度等参数。使用方法:进入设置页面后在地址栏的地址后加上&powertoy=musicvideo,然后在customize->Modules中添加。
    目前以上功能都还只支持Internet Explorer,而且所有的设置必须在Spaces的英文界面下完成。
    20/09/2005

    留下你的脚印!

     Leave your message here and do not forget to leave your name or nickname, so that I can recognize you.
    Thank you very much for your collaboration!
    Hit Counter留下你的脚印!让我记得你是谁!come here to leave your message to me :)
    To Stop Any Music Or Video From Playing Simply Press "ESC"

    Blog搜索引擎


    不出所料,Google终于推出了
    Blog搜索引擎

    和MSN Search的Feed搜索选项比起来,Google Blog Search看起来更加像其它普通的Blog搜索引擎,用起来也方便很多。Google Blog Search的搜索结果支持RSS和Atom格式的输出。而且通过搜索参数,我们可以进行Blog标题、文章标题、文章作者、Blog地址的搜索。可惜的是,Google Blog Search目前索引的Blog数量只有800万(Technorati为1700万)。不过,它的索引速度非常快,用来追踪热点事件还是很不错的。

    同时,Google也把这个搜索引擎置入了Blogger网站。你也可以在用户控制面板和Blogger Navbar进行搜索。

    以Google的搜索技术和品牌效应,特别是它在Blogger中的高关注度,相信Google Blog Search会迅速成为最常用的Blog搜索引擎之一。在这样的情况下,2个月前就开始测试Blog Search的Yahoo应该也很快会开放Blog搜索引擎。
    基本酒知识

    一 酒的化学知识

      酒是多种化学成份的混合物,酒精是其主要成份,除此之外,还有水和众多的化学物质。这些化学物质可分为酸、酯、醛、醇等类型。决定酒的质量的成份往往含量很低,但种类却非常多。这些成份含量的配比非常重要。
      饮料酒中都含有酒精,酒精的学名是乙醇,分子式:CH3─CH2─OH,分子量为46.
      糖转化成乙醇的化学反应式:
      C6H12O6→2CH3CH2OH+2CO2

    二 酒在人体内的吸收

      酒精无需经过消化系统而可被肠胃直接吸收。酒进入肠胃后,进入血管,饮酒后几分钟,迅速扩散到人体的全身。酒首先被血液带到肝脏,在肝脏过滤后,到达心脏,再到肺,从肺又返回到心脏,然后通过主动脉到静脉,再到达大脑和高级神经中枢。酒精对大脑和神经中枢的影响最大。
      人体本身也能合成少量的酒精,正常人的血液中含有0.003%的酒精。血液中酒精浓度的致死剂量是0.7%。

    三 酒的度数

      酒的度数表示酒中含乙醇的体积百分比,通常是以20℃时的体积比表示的,如50度的酒,表示在100毫升的酒中,含有乙醇50毫升(20℃).
      表示酒精含量也可以用重量比,重量比和体积比可以互相换算.
      西方国家常用proof表示酒精含量,规定200proof为酒精含量为100%的酒.如100proof的酒则是含酒精50%.

     啤酒的度数:

      啤酒的度数则不表示乙醇的含量,而是表示啤酒生产原料,也就是麦芽汁的浓度,以12度的啤酒为例,是麦芽汁发酵前浸出物的浓度为12%(重量比).麦芽汁中的浸出物是多种成分的混合物,以麦芽糖为主.
      啤酒的酒精是由麦芽糖转化而来的,由此可知,酒精度低于12度.如常见的浅色啤酒,酒精含量为3.3-3.8%;浓色啤酒酒精含量为4-5%.

    五 干酒和甜酒

      葡萄酒和黄酒,常常分为干型酒和甜型酒,在酿酒业中,用"干"(dry)表示酒中含糖量低,糖份大部分都转化成了酒精.还有一种"半干酒",所含的糖份比"干"酒较高些.甜,说明酒中含糖份高,酒中的糖份没有全部转化成酒精.还有半甜酒,浓甜酒.

    六 酒瓶上的英文标记:

      酒瓶上往往有一些英文标记,表明酒的品质,不同的国家有不同的表示方法.
      法国酒法规定:只有在夏郎德省(Charentes)及滨海夏郎德地区的少数地点,栽培几个特定的葡萄品种,利用壶式蒸馏锅,直火蒸馏所得的蒸馏液,贮存在橡木桶内,经过若干年陈酿老熟的蒸馏酒,才批准使用"可涅克"(Cognac)的商标.其它地区,既使用同样方法酿制成的蒸馏酒,不能用"可涅克"名称.
      如法国可涅克酒(白兰地酒)的酒瓶上,常常可看到以下标记:

    标 记  英文全称 备   注
    Three Stars   三星,贮藏4.5年以下.
    V.S.O.P. Very Superior Old Pale 非常优质的陈年浅色白兰地至少贮藏4.5年的白兰地,色较浅,
    V.S.O. Very Special Old  
    V.V.S.O. Very Very Special Old Pale  
    V.S.O.D. Very Superior Old Dark  
    Reserve   保留
    Extra    特级
    X.O Extra Old 陈年特级
    Cordon Blue   蓝饰带
    V.S.E.P. Very Superior Extra Pale 说明这是"极高档的蒸馏酒",常见于美国市场


    七 法国香槟酒含糖量的表示方法:

      EXTRA-SEC   含糖百分之一到百分之二
      SEC      含糖百分之二到百分之五
      DEMI-SEC    含糖百分之四到百分之六
      DOUX      含糖进分之八到百分之十

    八 金酒(Gin)

      金酒是一种再制酒,它是用高酒度的中性酒为酒基,加入桧属植物的浆果或其它风味料,再次蒸馏后得到的产品。配制的金酒无须再次蒸馏,是用桧属植物的香油或其它风味料调配而成的。

    九 俄得克(Vodka)和兰姆酒

      俄得克是一种中性烈性酒,无色、无味,无香气及无任何特征。在制造时,经过多次蒸馏,或蒸馏后用活性碳处理。在俄得克中加入某种风味料,该酒就具有这种风味料的特征,因而也用这种风味料的名称命名。
      兰姆酒是用甘蔗汁或糖蜜为原料,经发酵、蒸馏而得到的烈性酒。在靠近赤道的一些国家产量较大。


    Google Talk

    试用Google Talk
    Google Talk 下载
    今天测试发现性能很不错!
    1、Google Talk安装软件只有900k大小,在如此紧凑的尺寸里完成文本和语音两种通讯很不容易。
    2、聊天界面相当清爽,语音聊天的时候显示一个表示通讯速度的图标,很实用;
    3、只有Gmail的用户才能够登录Google Talk.
                       最后需要gmail的朋友给我留下你们的e-mail,我这有50份邀请分享给大家!

    中秋佳节快乐


    明月几时有

    把酒问青天

    不知天上宫阙

    今昔是何年

    我欲乘风归去

    又恐琼楼玉宇

    高处不胜寒

    起舞弄清影

    何似在人间

    转朱阁

    低绮户

    照无眠不应有恨

    何事长向别时圆

    人有悲欢离合

    月有阴晴圆缺

    此事古难全

    但愿人长久

    千里共婵娟