随笔-314  评论-209  文章-0  trackbacks-0
转自:http://www.iteye.com/topic/255397

1.那即将离我远去的

用buffalo作为我的ajax类库也有些历史了,几乎是和Spring同时开始接触的.

按照官方的方式,Buffalo与Spring的集成是很简单:

    在Spring中配置一个BuffaloServiceConfigure bean,把spring托管的服务在其中声明即可,Buffalo可以通过ServletContext得到Spring的WebApplicationContext,进而得到所需的服务:

Java代码 复制代码 收藏代码
  1. <bean name="buffaloConfigBean"    
  2.                 class="net.buffalo.service.BuffaloServiceConfigurer">    
  3.                 <property name="services">    
  4.                         <map>    
  5.                                 <entry key="springSimpleService">    
  6.                                         <ref bean="systemService" />    
  7.                                 </entry>    
  8.                                 <entry key="springSimpleService2">    
  9.                                         <ref bean="systemService2" />    
  10.                                 </entry>    
  11.                         </map>    
  12.                 </property>    
  13.  </bean>   

 

     似乎很简单,但,有没有觉得似乎很傻?只是把Spring里已经配置好的bean再引用一次而已,

一旦面临协作开发,和所有的全局配置文件一样,BuffaloServiceConfigure bean下面就会囊括几十上百个service ref,一大堆人围着这个配置文件转,CVS冲突就成了家常便饭了,苦恼不已.当然,按我们这么多年的开发经验是不会出现这种低级错误的,早早的在项目设计阶段就会按模块划分出多个配置文件,一人独用,无需和别人共享配置,轻松面对冲突问题,带来的局面就是每个包里都塞着一个buffalo.xml,一个项目里配置文件到处有,不断得copy/paste,层层套套,那可不是硕果累累的满足感.

     当然,Spring本身在2.5之前也因XML配置繁琐而让人诟病,Guice才能异军突起,那时Spring比Buffalo的配置更多,所以Buffalo的问题也就不是问题了.但有一天,我终于要正式升级到Spring2.5.

     世界清静了!使用annotation,看到怎么多配置文件消失,看到简洁的Bean/MVC配置,呵呵,还真是令人心情愉悦的.

     诶,等等,怎么还有大堆XML?哦?原来是Buffalo...

     Buffalo像个刺头,傻愣愣地杵在XML里.

 

2.于是我开始把Buffalo也Annotation化.

 

话说Spring的扩展能力还是ganggang的,一天时间,就有成果了.

先写个注解:

Java代码 复制代码 收藏代码
  1. package cn.tohot.common.annotation;   
  2.   
  3. import java.lang.annotation.ElementType;   
  4. import java.lang.annotation.Retention;   
  5. import java.lang.annotation.RetentionPolicy;   
  6. import java.lang.annotation.Target;   
  7.   
  8. /**  
  9.  * buffalo扩展接口,用于表明该类是一个buffalo服务.  
  10.  * @author tedeyang  
  11.  *  
  12.  */  
  13. @Retention(RetentionPolicy.RUNTIME)   
  14. @Target(ElementType.TYPE)   
  15. public @interface Buffalo {   
  16.     /**  
  17.      * @return 远程调用时的服务名.  
  18.      */    
  19.     String value();   
  20. }  

 

接着再写Spring的扩展

 

Java代码 复制代码 收藏代码
  1. /**  
  2.  *   
  3.  */  
  4. package cn.tohot.common.annotation;   
  5.   
  6. import java.util.HashMap;   
  7.   
  8. import net.buffalo.service.BuffaloServiceConfigurer;   
  9.   
  10. import org.apache.log4j.Logger;   
  11. import org.springframework.beans.BeansException;   
  12. import org.springframework.beans.factory.DisposableBean;   
  13. import org.springframework.beans.factory.FactoryBean;   
  14. import org.springframework.beans.factory.InitializingBean;   
  15. import org.springframework.beans.factory.config.BeanPostProcessor;   
  16.   
  17. /**  
  18.  * 该类作为FactoryBean可以无缝替换buffalo 2.0自带的配置类,并使用annotation进行配置.  
  19.  * @author tedeyang  
  20.  *  
  21.  */  
  22. @SuppressWarnings("unchecked")   
  23. public class BuffaloAnnotationServiceFactoryBean implements FactoryBean, InitializingBean, DisposableBean, BeanPostProcessor {   
  24.     private static final Logger log = Logger.getLogger(BuffaloAnnotationServiceFactoryBean.class);   
  25.   
  26.     private BuffaloServiceConfigurer buffaloConfigurer = null;   
  27.   
  28.     public BuffaloAnnotationServiceFactoryBean() {   
  29.         buffaloConfigurer = new BuffaloServiceConfigurer();   
  30.         buffaloConfigurer.setServices(new HashMap());   
  31.     }   
  32.   
  33.     private void addBuffaloBean(String buffaloServiceName,Object bean) {   
  34.         buffaloConfigurer.getServices().put(buffaloServiceName, bean);   
  35.         log.info("Add a buffalo service :"+buffaloServiceName);   
  36.     }   
  37.   
  38.     public Object getObject() throws Exception {   
  39.         return this.buffaloConfigurer;   
  40.     }   
  41.   
  42.     public Class getObjectType() {   
  43.         return BuffaloServiceConfigurer.class;   
  44.     }   
  45.   
  46.     public boolean isSingleton() {   
  47.         return true;   
  48.     }   
  49.   
  50.     public void afterPropertiesSet() throws Exception {   
  51.     }   
  52.   
  53.     public void destroy() throws Exception {   
  54.         if (buffaloConfigurer != null)   
  55.             buffaloConfigurer.setServices(null);   
  56.         buffaloConfigurer = null;   
  57.     }   
  58.     
  59.     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {   
  60.         return bean;   
  61.     }   
  62.   
  63.     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {   
  64.         log.debug("find a bean:"+beanName);   
  65.         if (bean.getClass().isAnnotationPresent(Buffalo.class)) {   
  66.             Buffalo buffalo = bean.getClass().getAnnotation(Buffalo.class);   
  67.             addBuffaloBean(buffalo.value(), bean);    
  68.         }   
  69.         return bean;   
  70.     }   
  71.   
  72. }  

 

 主要思路是用FactoryBean替换原BuffaloServiceConfigurer,并挂上BeanPostProcessor的钩子,检测一下annotation,发现buffalo服务就添加到原BuffaloServiceConfigurer中去.

 

3.今天我这样配置Buffalo:

Java代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  
  4.     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
  6.      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd   
  7.      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd   
  8.      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">   
  9.   
  10.     <!-- Spring Annotation配置, 自动搜索组件 -->   
  11.     <context:component-scan base-package="cn.tohot.demo"/>    
  12.     <bean id="buffalo"   class="cn.tohot.common.annotation.BuffaloAnnotationServiceFactoryBean" />    
  13. </beans>  
 

 服务端的Buffalo bean 类:

Java代码 复制代码 收藏代码
  1. package cn.tohot.demo;   
  2.   
  3. import org.springframework.stereotype.Service;   
  4.   
  5. import cn.tohot.common.annotation.Buffalo;   
  6.   
  7. @Service     //声明Spring bean,   
  8. @Buffalo("testbean"//声明一个名为"testbean"的Buffalo service   
  9. public class BuffaloBeanTestService {   
  10.     public String run() {   
  11.         System.out.println("run");   
  12.         return "run";   
  13.     }   
  14. }  

 很简洁,不是吗?

posted on 2011-08-26 09:21 xzc 阅读(231) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: