以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 Java/Eclipse 』  (http://bbs.xml.org.cn/list.asp?boardid=41)
----  [合集] 关于magic aop的一点细节问题 (转载)  (http://bbs.xml.org.cn/dispbbs.asp?boardid=41&rootid=&id=10292)


--  作者:admin
--  发布时间:9/23/2004 12:40:00 AM

--  [合集] 关于magic aop的一点细节问题 (转载)
● [合集] 关于magic aop的一点细节问题 (转载)发信人: diaochong (静静的雕虫~~小猪), 信区: J2EE
标  题: [合集] 关于magic aop的一点细节问题 (转载)
发信站: BBS 水木清华站 (Wed Mar 31 16:56:00 2004), 站内

【 以下文字转载自 JavaClub 讨论区 】
发信人: diaochong (静静的雕虫~~小猪), 信区: JavaClub
标  题: [合集] gty,关于magic aop的一点细节问题
发信站: BBS 水木清华站 (Wed Mar 31 16:54:29 2004), 站内

☆─────────────────────────────────────☆  
  microweb (深呼吸,闭好你的眼睛) 于  (Sat Mar  1 18:04:34 2003)  提到:

1.源代码疑点:aspect中对interface的建索引是连同original class
                本身也加了进去,无论它是否是interface;而在interfaces
                初始化的时候,却对其作了区分,original 为class则不加入
                为interface则加入?
                Interceptor设有EMPTY_INTERCEPTORS,初始化的时候若为null
                则设为EMPTY_INTERCEPTORS,但接着对其索引时候,判断用的是
                interceptor.length=0;

                偶不能确定其是否有问题,但觉得代码出现逻辑上处理不一致
                是否应该统一一下,呵呵

  2.一个问题:  如果偶想在已有的代码中把某个object 进行intercept,但这个
               object在n多地方用到,怎么办啊



☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Sat Mar  1 18:52:21 2003)  提到:


//aspect中对interface的建索引是连同original class本身也加了进去,
//无论它是否是interface

对interface的建索引的代码是
        for (int i = 0;i< sideAspects.length;i++)
                        indexInterface(sideAspects[i].getOriginalClass(),i);
这里是为sideAspects的originalClass(都是interface)建索引,目的
是提高把方法传递给sideAspect时的速度。

//在interfaces初始化的时候,却对其作了区分,original 为class则不加入
//为interface则加入?

这里是根据cglib的接口做的转换,前面已经说过。

//Interceptor设有EMPTY_INTERCEPTORS,初始化的时候若为null
//则设为EMPTY_INTERCEPTORS,但接着对其索引时候,判断用的是
//interceptor.length=0;

这是因为用户可能也设置一个空interceptor数组。

//如果偶想在已有的代码中把某个object 进行intercept,但这个
//object在n多地方用到,怎么办啊

一般来说,client代码根据方法和对象打交道的,Proxy对象是源对象
的一个代理,这对client来说是透明的。
当然,还是有一些情况会出错,但是也可以在代码中避免,例如:

a)直接取对象的字段(field)
        userProxy.name
  这个显然取不到实际目标对象的name,但在习惯上,一般用setter和
  getter方法。

b)取对象的Class做运算
    userProxy.getClass().equals(User.class)
  将会返回false
  但是可以用下面的代码代替
        Aspect.getAspectInstance(userProxy).getAspect().
                getOriginalClass().equals(User.class)
【 在 microweb (深呼吸,闭好你的眼睛) 的大作中提到: 】                          
:   1.源代码疑点:aspect中对interface的建索引是连同original class               
:                 本身也加了进去,无论它是否是interface;而在interfaces         
:                 初始化的时候,却对其作了区分,original 为class则不加入        
:                 为interface则加入?                                           
:                 Interceptor设有EMPTY_INTERCEPTORS,初始化的时候若为null        
:                 则设为EMPTY_INTERCEPTORS,但接着对其索引时候,判断用的是       
:                 interceptor.length=0;                                         
:                 偶不能确定其是否有问题,但觉得代码出现逻辑上处理不一致        
:                 是否应该统一一下,呵呵                                        
:   2.一个问题:  如果偶想在已有的代码中把某个object 进行intercept,但这个      
:                object在n多地方用到,怎么办啊                                  
: ...................                                                           



☆─────────────────────────────────────☆  
  microweb (深呼吸,闭好你的眼睛) 于  (Sun Mar  2 12:17:56 2003)  提到:

Thanks ahead!

【 在 gty (宜良-丽江-蝴蝶泉) 的大作中提到: 】                                   
: //aspect中对interface的建索引是连同original class本身也加了进去,             
: //无论它是否是interface                                                       
: 对interface的建索引的代码是                                                   
:         for (int i = 0;i< sideAspects.length;i++)                             
:                         indexInterface(sideAspects[i].getOriginalClass(),i);  

: 这里是为sideAspects的originalClass(都是interface)建索引,目的               
~~~~~~~~~~~~~~~~~偶觉得问题就在这里啊,呵呵
                         original本身可能不是interface,
                           里面代码是没有判断啊:
---------------------------------------------

private void indexInterface(Class interfaceClass, int instanceIndex) {
if (!interfacesIndex.containsKey(interfaceClass)) {
interfacesIndex.put(interfaceClass, new Integer(instance
Index));
                }
                Class[] interfaces = interfaceClass.getInterfaces();
//注意:上面没有判断是否为original,下面则全部都是
                for (int i = 0; i < interfaces.length; i++) {
                        Class superInterface = interfaces[i];
                        indexInterface(superInterface, instanceIndex);
                }
---------------------------------------------

: 是提高把方法传递给sideAspect时的速度。                                        
: //在interfaces初始化的时候,却对其作了区分,original 为class则不加入          
: //为interface则加入?                                                         
: 这里是根据cglib的接口做的转换,前面已经说过。                                 
: //Interceptor设有EMPTY_INTERCEPTORS,初始化的时候若为null                      
: //则设为EMPTY_INTERCEPTORS,但接着对其索引时候,判断用的是                     
: //interceptor.length=0;                                                       
: 这是因为用户可能也设置一个空interceptor数组。                                 
: //如果偶想在已有的代码中把某个object 进行intercept,但这个                    
: //object在n多地方用到,怎么办啊                                               
: 一般来说,client代码根据方法和对象打交道的,Proxy对象是源对象                 
: 的一个代理,这对client来说是透明的。                                          
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        不错,的确是对client是透明的,但偶要保证这种透明,需要偶把原来
调用某个class object的地方全部替换成object proxy才行啊
如:对每个文件里面node对象的使用,偶得想办法把它全部替换成node proxy
才行嘛
       看了aspectj,由于它是编译时候把interceptor插入的,所以
不用改代码,
并不知道这个有什么解决方案:)

BTW,如果是偶理解出问题,不要笑话了,呵呵


: 当然,还是有一些情况会出错,但是也可以在代码中避免,例如:                    
: a)直接取对象的字段(field)                                                     
:         userProxy.name                                                        
:   这个显然取不到实际目标对象的name,但在习惯上,一般用setter和                
:   getter方法。                                                                
: b)取对象的Class做运算                                                         
:     userProxy.getClass().equals(User.class)                                   
:   将会返回false                                                               
:   但是可以用下面的代码代替                                                    
:         Aspect.getAspectInstance(userProxy).getAspect().                      
:                 getOriginalClass().equals(User.class)




☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Sun Mar  2 15:11:26 2003)  提到:

Thank you too:)

//Class[] interfaces = interfaceClass.getInterfaces();
//注意:上面没有判断是否为original,下面则全部都是

这里的interfaceClass是一个Class对象,它的getInterfaces()方法是返回这个
Class实现的所有interface(父interface),和Aspect类没有关系。
而调用这个方法之前,originalClass还没有加入到interfaces[]数组中呢。

//不错,的确是对client是透明的,但偶要保证这种透明,需要偶把原来
//调用某个class object的地方全部替换成object proxy才行啊
//如:对每个文件里面node对象的使用,偶得想办法把它全部替换成node proxy
//才行嘛
我终于明白了你的意思。是这个样子的,问题可以分成两种情况:
1、对象的创建。
        显然,这里不能用new,但可以用factory模式。和aspectj相比这是缺点,也是
        优点。优点在于,在系统里不是任何地方都想要相同的proxy,例如在客户端,
        我想要的是有RemoteInterceptor的proxy,在服务器端,我想要有PoolInterceptor
        的proxy。这种需求,用factory很容易解决。

2. 对象的使用,应该和平常用法没有区别。例如在MagicsServer对Entity对象的操作中,

//example code 1
EntityHome userHome = MagicContext.getEntityHome(User.class);  //Factory类

User user = (User)userHome.load("guty"); //这里实际上加载了一个UserProxy1,但是
                                         //它继承了User类。在MagicServer里,
                                         //XXXHome.load()出来的是一个远程Proxy,
                                         //所有操作直接转到服务器端

logger.debug(user.getName());
user.verifyPwd("123456");               //直接到后台去验证密码
user.setAge(100);                       //直接修改了后台数据库
userHome.delete("guty");                    //删除

//example code 2
User user1 = (User)userHome.findById("guty"); //这里也加载了一个UserProxy2,
                                        //同样继承User类。但是它只是一个
                                        //LazyLoad的本地对象
user1.getName();                        //本地调用
user.verifyPwd("123456");               //由于verifyPwd使用了其他远程方法,所
                                        //以还会在调用过程中访问远程
user1.setAget(100);                     //修改本地对象,服务器还没有改变。
userHome.update(user1);//修改远程对象
Collection groups = user1.getGroups();  //lazyload,将user所属的group从服务器
                                        //load到本地对象中
userHome.delete("guty");                //删除对象

【 在 microweb (深呼吸,闭好你的眼睛) 的大作中提到: 】                          
:  Thanks ahead!                                                                
:                                    ~~~~~~~~~~~~~~~~~偶觉得问题就在这里啊,呵呵
:                          original本身可能不是interface,                      
:                            里面代码是没有判断啊:                             
: ---------------------------------------------                                 
: private void indexInterface(Class interfaceClass, int instanceIndex) {
:                 if (!interfacesIndex.containsKey(interfaceClass)) {
:                         interfacesIndex.put(interfaceClass, new Integer(instan
ceIndex));                                                                      
:                 }                                                             
:                 Class[] interfaces = interfaceClass.getInterfaces();          
:                 //注意:上面没有判断是否为original,下面则全部都是            
: ...................                                                           

☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Sun Mar  2 18:31:39 2003)  提到:

这个实体对象调用和实体bean好像没有太大的区别啊, 好像仅仅增加了
J2EE里要用特定模式才能实现的东西.后台采用Hibernate映射数据库
还是不绑定到O-R工具上呢?
其实我觉得实体对象完全可以不增加远程调用 功能啊, 只有非常简单的数据访问
逻辑才不至于降低性能吧, 否则在集成层前面加上一层逻辑层, 处理对实体的多次
调用, 部署在同一主机上更好吧
【 在 gty (宜良-丽江-蝴蝶泉) 的大作中提到: 】                                   
: Thank you too:)                                                               
: //Class[] interfaces = interfaceClass.getInterfaces();                        
: //注意:上面没有判断是否为original,下面则全部都是                            
: 这里的interfaceClass是一个Class对象,它的getInterfaces()方法是返回这个        
: Class实现的所有interface(父interface),和Aspect类没有关系。                  
: 而调用这个方法之前,originalClass还没有加入到interfaces[]数组中呢。           
: //不错,的确是对client是透明的,但偶要保证这种透明,需要偶把原来              
: //调用某个class object的地方全部替换成object proxy才行啊                      
: //如:对每个文件里面node对象的使用,偶得想办法把它全部替换成node proxy        
: //才行嘛                                                                      
: 我终于明白了你的意思。是这个样子的,问题可以分成两种情况:                    
: ...................                                                           

☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Sun Mar  2 18:37:40 2003)  提到:

用这种方式相当于又新增加了一种规范吧, 呵呵
就像现在java世界里MVC框架满天飞, 实际上也增加了开发者的
负担, 每个实现都不一样, 没有标准, 而且这是应用服务器,
也导致了应用没法移至

【 在 UltraFool (遥望·遐想·感伤) 的大作中提到: 】                             
: 这个实体对象调用和实体bean好像没有太大的区别啊, 好像仅仅增加了                
: J2EE里要用特定模式才能实现的东西.后台采用Hibernate映射数据库                  
: 还是不绑定到O-R工具上呢?                                                      
: 其实我觉得实体对象完全可以不增加远程调用 功能啊, 只有非常简单的数据访问       
: 逻辑才不至于降低性能吧, 否则在集成层前面加上一层逻辑层, 处理对实体的多次      
: 调用, 部署在同一主机上更好吧                                                  


☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Mon Mar  3 01:07:42 2003)  提到:


在我的例子里面,程序员需要写的只有两个POJO类,
User和Group,最普通的Java Bean.

应该不会增加什么负担吧。

【 在 UltraFool (遥望·遐想·感伤) 的大作中提到: 】                             
: 用这种方式相当于又新增加了一种规范吧, 呵呵                                    
: 就像现在java世界里MVC框架满天飞, 实际上也增加了开发者的                       
: 负担, 每个实现都不一样, 没有标准, 而且这是应用服务器,                         
: 也导致了应用没法移至                                                          




☆─────────────────────────────────────☆  
gty (宜良-丽江-蝴蝶泉) 于  (Mon Mar  3 01:17:09 2003)  提到:


J2EE已经把系统分析得很好了,现在只是要
用另外一种技术手段去简化它而已。

现在是绑定在Hibernate上,因为Hibernate
支持POJO,也就是,从另一层意思上说,
程序又没有“绑定”。

J2EE中提倡Session Facade模式,是因为EB的
性能问题。但Magic Server中就没有这样的
问题,因为同一个"User",在客户端是有remote
和Transaction功能的,在服务器端,却又是
一个轻量级的"User"。

现在性能问题解决了,为什么还要多此一举再
写Session Facade呢?

【 在 UltraFool (遥望·遐想·感伤) 的大作中提到: 】                             
: 这个实体对象调用和实体bean好像没有太大的区别啊, 好像仅仅增加了                
: J2EE里要用特定模式才能实现的东西.后台采用Hibernate映射数据库                  
: 还是不绑定到O-R工具上呢?                                                      
: 其实我觉得实体对象完全可以不增加远程调用 功能啊, 只有非常简单的数据访问       
: 逻辑才不至于降低性能吧, 否则在集成层前面加上一层逻辑层, 处理对实体的多次      
: 调用, 部署在同一主机上更好吧                                                  


☆─────────────────────────────────────☆  
  UltraFool (遥望·遐想·感伤) 于  (Mon Mar  3 17:33:50 2003)  提到:

好像session facade主要就是解决一个用例需要(一个事务中)多次的持久层访问
如果实体对象中没有包含特定的商务逻辑怎样避免多次远程调用,而且简化事务啊
我觉得远程调用的功能在逻辑层是否更好呢?

【 在 gty (宜良-丽江-蝴蝶泉) 的大作中提到: 】                                   
: J2EE已经把系统分析得很好了,现在只是要                                        
: 用另外一种技术手段去简化它而已。                                              
: 现在是绑定在Hibernate上,因为Hibernate                                        
: 支持POJO,也就是,从另一层意思上说,                                          
: 程序又没有“绑定”。                                                          
: J2EE中提倡Session Facade模式,是因为EB的                                      
: 性能问题。但Magic Server中就没有这样的                                        
: 问题,因为同一个"User",在客户端是有remote                                    
: 和Transaction功能的,在服务器端,却又是                                       
: 一个轻量级的"User"。                                                          
: 现在性能问题解决了,为什么还要多此一举再                                      
: ...................

☆─────────────────────────────────────☆  
UltraFool (遥望·遐想·感伤) 于  (Mon Mar  3 17:47:54 2003)  提到:

AOP确实很cool, 看了看去年的程序员文章, 虽然只是AspectJ, 但是也感到
确实可以大大简化应用服务器原来提供的横切关注点服务
AspectJ好像可以将应用服务器提供的一些底层功能
在语言级别就去完成?
等有空了再学习rickard的思想...其实我现在说的都还是瞎子摸鱼
我个人觉得现在的EJB还是挺简单的, 可能我没做过什么项目
不过一个新的东西要成熟可能还有很多曲折吧, 技术探索也许相对容易,
大的风险吧, 而且新的平台能否在实际应用中经得住考研也要时间检验,
而且如果这种基础性的平台没有标准的话, 将会导致天下大乱了,
也许开源软件去打头阵, 还是需要Sun之类的认可, 可能又要好多年
【 在 gty (宜良-丽江-蝴蝶泉) 的大作中提到: 】                                   
: 在我的例子里面,程序员需要写的只有两个POJO类,                                
: User和Group,最普通的Java Bean.                                               
: 应该不会增加什么负担吧。                                                      


※ 修改:·diaochong 于 Mar 31 17:03:43 修改本文·[FROM:   166.111.102.*]        

索引页面|上一篇|下一篇


W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
328.125ms