标签:
最近一直在准备构建一个rpc服务,为避免重复造轮子,在择取的过程中发现了很多优秀的rpc架构。
1:common-rpc:http://my.oschina.net/liubingsmile/blog/387154
已经足够成熟。
2:基于akka的rpc
http://my.oschina.net/FengJ/blog/268387
现在仅仅对其初始化的时候 做小小的改动,方便使用。
原有代码对服务的注册:
// Server 加入发布的服务
Map < Class <?>, Object > beans = new HashMap < Class <?>, Object >();
beans . put ( ExampleInterface . class , new ExampleInterfaceImpl ());
这样服务多了,很不方便。
现在选择基于spring的其中一种方式,略微改动,主要是基于Java的@interface注解,加上spring的bean工厂。原理比较简单。
首先创建一个spring的配置文件:
rpcServerContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--service-->
<context:component-scan base-package="com.topteam.example.service.impl"/>
<bean id="rpcServer" class="com.topteam.rpc.anotaion.RpcServer"></bean>
</beans>
RpcServer :扫描注解接口,进行akka-rpc服务映射的初始化
public class RpcServer implements ApplicationContextAware, InitializingBean
{
/**
* 存放 服务名 与 服务对象 之间的映射关系
*/
private Map<Class<?>, Object> handlerMap = new HashMap<Class<?>, Object>();
public void setApplicationContext(ApplicationContext ctx) throws BeansException
{
// 扫描带有 RpcService 注解的类并初始化 handlerMap 对象
Map<String, Object> serviceBeanMap = ctx.getBeansWithAnnotation(RpcService.class);
if (MapUtils.isNotEmpty(serviceBeanMap))
{
for (Object serviceBean : serviceBeanMap.values())
{
RpcService rpcService = serviceBean.getClass().getAnnotation(RpcService.class);
handlerMap.put(rpcService.value(),serviceBean);
}
this.setHandlerMap(handlerMap);
}
}
public void afterPropertiesSet() throws Exception
{
// TODO Auto-generated method stub
}
public Map<Class<?>, Object> getHandlerMap()
{
return handlerMap;
}
public void setHandlerMap(Map<Class<?>, Object> handlerMap)
{
this.handlerMap = handlerMap;
}
}
RpcBootstrap:用来扫描
public class RpcBootstrap
{
private ClassPathXmlApplicationContext application;
public void init()
{
System.out.println("*************__init__************");
ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("rpcServerContext.xml");
this.application = application;
}
public void close()
{
System.out.println("**************__close__***********");
}
public ClassPathXmlApplicationContext getApplication()
{
return application;
}
public void setApplication(ClassPathXmlApplicationContext application)
{
this.application = application;
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface RpcService
{
/**
* 服务接口类
*/
Class<?> value();
}
扫描注解的接口:
public class RpcServer implements ApplicationContextAware, InitializingBean
{
/**
* 存放 服务名 与 服务对象 之间的映射关系
*/
private Map<Class<?>, Object> handlerMap = new HashMap<Class<?>, Object>();
public void setApplicationContext(ApplicationContext ctx) throws BeansException
{
// 扫描带有 RpcService 注解的类并初始化 handlerMap 对象
Map<String, Object> serviceBeanMap = ctx.getBeansWithAnnotation(RpcService.class);
if (MapUtils.isNotEmpty(serviceBeanMap))
{
for (Object serviceBean : serviceBeanMap.values())
{
RpcService rpcService = serviceBean.getClass().getAnnotation(RpcService.class);
handlerMap.put(rpcService.value(),serviceBean);
}
this.setHandlerMap(handlerMap);
}
}
public void afterPropertiesSet() throws Exception
{
// TODO Auto-generated method stub
}
public Map<Class<?>, Object> getHandlerMap()
{
return handlerMap;
}
public void setHandlerMap(Map<Class<?>, Object> handlerMap)
{
this.handlerMap = handlerMap;
}
}
接口实现:
@RpcService(ExampleInterface.class)
public class ExampleInterfaceImpl implements ExampleInterface
{
/**
*
*/
private static final long serialVersionUID = 1L;
public String sayHello(String name)
{
System.out.println("Be Called !");
ExampleOtherBean bean = new ExampleOtherBean(name);
return "Hello " + bean.toString();
}
}
改造原有的spring主上下文:
spring-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.topteam.rpc.anotaion"/>
<bean id="bootstrap" class="com.topteam.rpc.bootstrap.RpcBootstrap" init-method="init" destroy-method="close"></bean>
<bean id="akkaRpcServer" class="com.topteam.rpc.server.AkkaRpcServer" init-method="start" destroy-method="close"></bean>
<bean id="akkaRpcClient" class="com.topteam.rpc.client.AkkaRpcClientFactory" scope="singleton"></bean>
</beans>
测试:
public class StringSupportTest
{
public static void main(String[] args)
{
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");
AkkaRpcServer akkaRpcServer = (AkkaRpcServer)applicationContext.getBean("akkaRpcServer");
final Config config = ConfigFactory
.parseString("akka.remote.netty.tcp.port=" + 2551)
.withFallback(ConfigFactory.parseString("akka.cluster.roles = [RpcServer]"))
.withFallback(ConfigFactory.load());
ActorSystem system = ActorSystem.create("EsbSystem", config);
// Server 加入发布的服务
//Map<Class<?>, Object> beans = new HashMap<Class<?>, Object>();
//beans.put(ExampleInterface.class, new ExampleInterfaceImpl());
/**
* 服务创建actors
*/
System.out.println(akkaRpcServer.getServices());
system.actorOf(Props.create(RpcServerActor.class, akkaRpcServer.getServices()), "rpcServer");
// int count = 10000;
//
// AkkaRpcClient client = AkkaRpcClient.getInstance();
// long start = System.currentTimeMillis();
//
// ExampleInterface example = client.getBean(ExampleInterface.class);
//
// for(int i = 0; i < count; i++)
// {
// System.out.println(example.sayHello("rpc_" + i));
// }
//
// long time = System.currentTimeMillis() - start;
// System.out.println("time :" + time);
}
/*
* private ApplicationContext applicationContext =new ClassPathXmlApplicationContext("classpath:spring-context.xml");
* @Test
public void akkaRpcServerSpringInjectTest()
{
AkkaRpcServer akkaRpcServer = applicationContext.getBean(AkkaRpcServer.class);
Assert.assertNotNull(akkaRpcServer);
}
@Test
public void akkaRpcClientFactoryInjectTest()
{
AkkaRpcClientFactory akkaRpcServer = applicationContext.getBean(AkkaRpcClientFactory.class);
Assert.assertNotNull(akkaRpcServer.getClient());
}*/
}
标签:
原文地址:http://my.oschina.net/u/2273085/blog/510909