博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SPRING注解发布RMI/HTTPInvoker/Hessian/Burlap服务
阅读量:6876 次
发布时间:2019-06-26

本文共 9053 字,大约阅读时间需要 30 分钟。

hot3.png

最近做系统重构,计划将多个系统的公共部分抽取出来作为一项公共服务,为以后项目维护和横向扩展奠定基础。

常用的服务发布方式有RMI / HTTPInvoker / Hessian / Burlap,关于这几类java远程服务的性能比较和优缺点大家可参考:http://www.cnblogs.com/jifeng/archive/2011/07/20/2111183.html ,本文着重讲解怎样使用自定的注解标签,结合SPRING将服务方便的发布出去。

一、 Maven配置

junit
junit
4.7
test
org.springframework
spring-core
3.1.1.RELEASE
org.springframework
spring-context
3.1.1.RELEASE
org.springframework
spring-beans
3.1.1.RELEASE
org.springframework
spring-webmvc
3.1.1.RELEASE
com.caucho
hessian
4.0.38
org.springframework
spring-test
3.1.1.RELEASE
org.eclipse.jetty
jetty-webapp
8.1.3.v20120416

二、自定义Annotation注解标签(RemoteService)

package org.springframework.remoting;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.stereotype.Component;@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface RemoteService {    ServiceType serviceType() default ServiceType.HTTP;    Class
serviceInterface();}

RemoteService辅助标签RmiServiceProperty,在发布RMI服务时,用来指定RMI服务发布的端口。

package org.springframework.remoting;import org.springframework.stereotype.Component;import java.lang.annotation.*;import java.rmi.registry.Registry;/** * Created by Administrator on 2014/12/8. */@Target({ ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documented@Componentpublic @interface RmiServiceProperty {    int registryPort() default Registry.REGISTRY_PORT;}

ServiceType,指定发布服务的类型

package org.springframework.remoting;public enum ServiceType {    HTTP, BURLAP, HESSIAN, RMI}

三、 定义Annotation标签解释器

public class ServiceAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter implements PriorityOrdered {    private int order = Ordered.LOWEST_PRECEDENCE - 1;    @Override    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {        RemoteService service = AnnotationUtils.findAnnotation(bean.getClass(), RemoteService.class);        Object resultBean = bean;        if (null != service) {            if (ServiceType.HTTP == service.serviceType()) {                if(!beanName.startsWith("/")){                    throw new FatalBeanException("Exception initializing  HttpInvokerService for "+beanName+",beanName should bean start with \"/\".");                }                HttpInvokerServiceExporter httpInvokerServiceExporter = new HttpInvokerServiceExporter();                httpInvokerServiceExporter.setServiceInterface(service.serviceInterface());                httpInvokerServiceExporter.setService(bean);                httpInvokerServiceExporter.afterPropertiesSet();                resultBean = httpInvokerServiceExporter;            } else if (ServiceType.HESSIAN == service.serviceType()) {                if(!beanName.startsWith("/")){                    throw new FatalBeanException("Exception initializing  HessianService for "+beanName+",beanName should bean start with \"/\".");                }                HessianServiceExporter hessianServiceExporter = new HessianServiceExporter();                hessianServiceExporter.setServiceInterface(service.serviceInterface());                hessianServiceExporter.setService(bean);                hessianServiceExporter.afterPropertiesSet();                resultBean = hessianServiceExporter;            } else if (ServiceType.BURLAP == service.serviceType()) {                if(!beanName.startsWith("/")){                    throw new FatalBeanException("Exception initializing BurlapService for "+beanName+",beanName should bean start with \"/\".");                }                BurlapServiceExporter burlapServiceExporter = new BurlapServiceExporter();                burlapServiceExporter.setServiceInterface(service.serviceInterface());                burlapServiceExporter.setService(bean);                burlapServiceExporter.afterPropertiesSet();                resultBean = burlapServiceExporter;            } else if (ServiceType.RMI == service.serviceType()) {                RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();                rmiServiceExporter.setServiceInterface(service.serviceInterface());                rmiServiceExporter.setService(bean);                RmiServiceProperty rmiServiceProperty = bean.getClass().getAnnotation(RmiServiceProperty.class);                if(rmiServiceProperty!=null){                    rmiServiceExporter.setRegistryPort(rmiServiceProperty.registryPort());                }                String serviceName = beanName;                if(serviceName.startsWith("/")){                    serviceName = serviceName.substring(1);                }                rmiServiceExporter.setServiceName(serviceName);                try {                    rmiServiceExporter.afterPropertiesSet();                } catch (RemoteException remoteException) {                    throw new FatalBeanException("Exception initializing RmiServiceExporter", remoteException);                }                resultBean = rmiServiceExporter;            }        }        return resultBean;    }    /******      参考附件     ******/}

四、重写Spring框架AnnotationConfigUtils

请注意package和Class Name必须一致

package org.springframework.context.annotation;public class AnnotationConfigUtils {    /******      参考附件     ******/	/**	 * Register all relevant annotation post processors in the given registry.	 * @param registry the registry to operate on	 * @param source the configuration source element (already extracted)	 * that this registration was triggered from. May be null.	 * @return a Set of BeanDefinitionHolders, containing all bean definitions	 * that have actually been registered by this call	 */	public static Set
registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, Object source) { Set
beanDefs = new LinkedHashSet
(4); if (!registry.containsBeanDefinition(SERVICE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ServiceAnnotationBeanPostProcessor.class); def.setSource(source); def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); beanDefs.add(registerPostProcessor(registry, def, SERVICE_ANNOTATION_PROCESSOR_BEAN_NAME)); } /******* 参考附件 *******/ return beanDefs; } /******* 参考附件 *******/}

五、发布服务

        服务接口

public interface HttpDateService {    public Date getDate();}

        发布服务

@RemoteService(serviceInterface = HttpDateService.class, serviceType = ServiceType.HTTP)public class HttpDateServiceImpl implements HttpDateService {    @Override    public Date getDate() {        return new Date();    }}
        SPRING基础配置

      其他类型的服务发布请参考附件。

六、测试服务

本次测试使用Junit4结合Spring容器测试服务。

Client Spring配置

   
   
 
服务测试基础类,使用注解(RunWith/ ContextConfiguration)初始化Spring容器,测试具体的逻辑前,先将项目发布到Jetty容器中。
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations ={"classpath:DateServiceTest-context.xml"})public class ServerRunner {    private static Server server;    @BeforeClass    public static void startWebapp() throws Exception {        server = new Server();        Connector connector = new SelectChannelConnector();        connector.setPort(8080);        server.addConnector(connector);        WebAppContext webAppContext = new WebAppContext();        webAppContext.setContextPath("/remoting");        webAppContext.setWar("src/main/webapp");        server.setHandler(webAppContext);        server.start();        System.out.println("syetem start sucess.");    }    @AfterClass    public static void stopWebapp() throws Exception {        server.stop();    }}

服务接口测试

public class HttpDateServiceTest extends ServerRunner {    @Resource(name = "httpDateService")    private HttpDateService httpDateService;    @Test    public void getGetDate() {        System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(httpDateService.getDate()));    }}

测试结果:

syetem start sucess.2014-12-09 10:43:34

源码地址:

转载于:https://my.oschina.net/damihui/blog/354055

你可能感兴趣的文章
用 zabbix 监测 snmptrap 的主动告警功能
查看>>
HDU1717 小数化分数2
查看>>
delphi 导入excel
查看>>
Linux下 FTP 常见错误 500 530等错误解决方法
查看>>
oracle asm
查看>>
VC基于单文档opengl框架
查看>>
openSUSE13.2安装ruby和rails
查看>>
python 高级函数
查看>>
F.Cards with Numbers
查看>>
简单入门Buffer
查看>>
Paint House II
查看>>
测试评审清单
查看>>
字节流数据的写出(输出)和读取(输入)
查看>>
OO第四阶段总结
查看>>
javascript总结02
查看>>
创建windows服务
查看>>
KSQL日期字段访问
查看>>
HTML5 入门基础
查看>>
Laravel 中的 Many-To-Many
查看>>
Codeforces 371C Hamburgers(二分基础题)
查看>>