注意事项:
1. 建议服务提供者使用main函数运行,不要在tomcat中运行(会多占用端口等)
2. 如果一个服务提供者必须是web项目,要部署在tomcat中,则需要在servlet启动后,调用MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);来注册服务优雅起停,测试表示如果不调用,则无法调用到服务,使用motan-manager查看服务,可以看到服务状态是Unavailable Server,如果值设置为false,服务也是不可用的
3. 服务提供者和服务消费者最好是在不同的tomcat中运行,不要运行于同一个tomcat中,原则是如果先运行了服务消费者,则会导致找不到服务方法,导致启动报错
4. 服务消费者的controller中无法直接引用motan服务,需要定义一个Service,然后在Service中引用对应的motan服务,原因应该是Controller与普通spring bean 所处理容器不同
主要过程如下:
一. 新建3个项目,分别是
motan-api 是对应的api接口
motan-server 是motan-api的实现,依赖motan-api
motan-client 调用motan-api的实现,依赖motan-api
二.motan-api是普通的工程,生成jar包,只有一个接口
package motan.demo.api;
public interface IHelloWorld {
public String hello(String name);
}
三.motan-server是一个web工程,
3.1 pom.xml配置如下
4.0.0
jzweb
motan-server
0.1
war
UTF-8
1.7
0.2.1
4.3.3.RELEASE
com.weibo
motan-core
${motan.version}
com.weibo
motan-springsupport
${motan.version}
com.weibo
motan-transport-netty
${motan.version}
com.weibo
motan-registry-consul
${motan.version}
com.weibo
motan-registry-zookeeper
${motan.version}
com.weibo
motan-protocol-yar
${motan.version}
org.apache.httpcomponents
httpcore
4.3.3
slf4j-api
org.slf4j
1.7.11
slf4j-log4j12
org.slf4j
1.7.11
jzweb
motan-api
0.1
org.springframework
spring-web
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-webmvc
${spring.version}
org.hibernate
hibernate-validator
5.3.0.Final
commons-io
commons-io
2.5
commons-codec
commons-codec
1.10
commons-fileupload
commons-fileupload
1.3.2
motan-server
org.apache.maven.plugins
maven-compiler-plugin
3.1
${project.build.jdk}
${project.build.sourceEncoding}
org.apache.maven.plugins
maven-war-plugin
2.6
false
3.2 在src/main/resources中添加spring.xml,内容如下
3.3 在src/main/resources目录中添加spring-mvc.xml配置文件
3.4 从官方拷贝log4j.properties文件到src/main/resources目录
3.5 因为这个一个web工程,要放在tomcat下运行,为了实现优雅的起启服务,需要定义一个ServletContextListener来启动或关闭服务MotanSwitcherUtil,经测试,如果不配置的话,通过servlet发布的服务将无法使用
package motan.demo.server.server.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import com.weibo.api.motan.common.MotanConstants;
import com.weibo.api.motan.util.MotanSwitcherUtil;
public class MotanServletContextListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent event) {
//这个时候spring已经初始化完成,调用以下的类来调整motan状态
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
}
}
```
#####3.5 实现类HelloWorldImpl实现api项目中的接口,如下,其中,MotanService是motan的服务注册注解
```java
package motan.demo.server.api.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.weibo.api.motan.config.springsupport.annotation.MotanService;
import motan.demo.api.IHelloWorld;
@MotanService
public class HelloWorldImpl implements IHelloWorld{
private Logger log = LoggerFactory.getLogger(getClass());
@Override
public String hello(String name) {
log.debug("hello,name");
return "hello,"+name;
}
}
3.6 配置web.xml文件,内容如下
contextConfigLocation
classpath*:spring.xml
org.springframework.web.context.ContextLoaderListener
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
spring_mvc_dispatcher
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath*:spring-mvc.xml
1
spring_mvc_dispatcher
/
motan.demo.server.listener.MotanServletContextListener
3.7 如果没有controller,不需要启动tomcat服务,可以直接使用main函数启动,类如下:
public class Main {
public static void main(String[] args) {
@SuppressWarnings("unused")
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
new String[] {"classpath*:spring.xml"});
MotanSwitcherUtil.setSwitcherValue(MotanConstants.REGISTRY_HEARTBEAT_SWITCHER, true);
System.out.println("server start...");
}
}
说明:这个配置过程中
1. zookeeper等信息在spring.xml中配置的
2. rpc实现类采用的是注解的方式
四.motan-client项目,这也是一个web工程
4.1 web.xml配置文件与motan-server项目相同
4.2 spring.xml配置文件调整如下:
4.3 spring-mvc.xml配置文件与server相同(如果没有controller,也可以不用配置)
4.4 定义一个Service,引用motan服务
@Service
public class SayHello {
@MotanReferer
private IHelloWorld hello;
private Logger log = LoggerFactory.getLogger(getClass());
public String say(String name){
String result = hello.hello(name);
System.out.println(result);
log.debug(result);
return result;
}
}
4.5 定义controller,引用Service
@RestController
public class HelloController {
@Autowired
private SayHello hello;
private Logger log = LoggerFactory.getLogger(getClass());
@RequestMapping("/hello/{name}")
@ResponseBody
public String hello(@PathVariable("name") String name){
String result = hello.say(name);
System.out.println(result);
log.debug(result);
return result;
}
}
4.6 如果这个项目也没有controller,则也可以直接使用main函数启动, 进行调用测试,内容如下
public class Main {
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] { "classpath:spring.xml" });
SayHello service = (SayHello) ctx.getBean(SayHello.class);
for (int i = 0; i < 10; i++) {
service.say("motan" + i);
Thread.sleep(1000);
}
System.out.println("motan demo is finish.");
System.exit(0);
}
}