这里简单介绍一下sping remoting的三种实现,http-invoker,hessian,burlap,spring对hessian,burlap做好很好的封装,很容易使用,下面介绍一下他们的配置
一、服务器端配置(applicationContext.xml):
<pre name="code" class="html"><?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:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.plateno.service" />
<bean id="beanNameUrlHandlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 类似rmi方式,采用java序列化,数据量较大 -->
<bean name="/httpInvokerService" class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="remoteService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
<!-- 采用hessian序列化,数据量最小 -->
<bean name="/hessianService" class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="remoteService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
<!-- xml传输数据,数据量比httpinvoker方式小 -->
<bean name="/burlapService" class="org.springframework.remoting.caucho.BurlapServiceExporter">
<property name="service" ref="remoteService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.plateno.interceptor.CommonInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
二、服务器端配置(web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
三、写一个service,再写一个serviceImpl就ok了。
四、客户端配置:
<pre name="code" class="html"><bean id="httpInvokerProxyFactoryBean" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:9999/server/httpInvokerService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
<bean id="hessianProxyFactoryBean" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:9999/server/hessianService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
<bean id="burlapProxyFactoryBean" class="org.springframework.remoting.caucho.BurlapProxyFactoryBean">
<property name="serviceUrl" value="http://localhost:9999/server/burlapService"/>
<property name="serviceInterface" value="com.plateno.platform.service.RemoteService"/>
</bean>
五、测试类:
@Autowired
private RemoteService remoteService;
@RequestMapping(value="/test")
public ModelAndView test(@RequestParam(value="name", required=false) String name) {
UserDTO dto = remoteService.getUser("hello");
System.out.println(dto);
Map<String, Object> model = new HashMap<String, Object>();
return new ModelAndView("test/hello", model);
}
加载@@@@@@@@
如果按照上面的方式,每发布一个接口,就得往xml文件写配置,很麻烦,下面来介绍工程自动发布接口,程序员像在一个工程写代码一个,写接口,写实现,客户端调用就ok了
1、给定包名,扫描包名下面的类(接口)参照spring实现:
package com.plateno.util;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
public class ClassPathScanning extends ClassPathScanningCandidateComponentProvider {
private List<String> classNameSet = new ArrayList<String>(20);
private List<Class<?>> clzSet = new ArrayList<Class<?>>(20);
public ClassPathScanning(boolean useDefaultFilters) {
super(useDefaultFilters);
}
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
private String resourcePattern = DEFAULT_RESOURCE_PATTERN;
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
public void getClassFromPackage(String basePackage) {
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + "/" + this.resourcePattern;
Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
for(Resource r : resources) {
if(r.isReadable()) {
MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(r);
ClassMetadata classMetadata = metadataReader.getClassMetadata();
if(!classMetadata.isIndependent()) {
continue;
}
String className = classMetadata.getClassName();
int index = className.lastIndexOf(".");
if(index > 0) {
String name = className.substring(index+1);
name = name.substring(0, 1).toLowerCase() + name.substring(1);
classNameSet.add(name);
clzSet.add(Class.forName(className));
}
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
public List<String> getClassNameSet() {
return classNameSet;
}
public List<Class<?>> getClzSet() {
return clzSet;
}
}
2、服务端发布接口:
package com.plateno.util;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.remoting.caucho.BurlapServiceExporter;
import org.springframework.remoting.caucho.HessianServiceExporter;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
public class BeanFactoryProxyServer implements BeanFactoryPostProcessor,ApplicationContextAware {
private ApplicationContext applicationContext;
private ConfigurableListableBeanFactory beanFactory;
private String basePackage = "com.plateno.platform.service";
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
// httpInvoker();
// hessian();
burlap();
}
private void httpInvoker() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
HttpInvokerServiceExporter exporter = new HttpInvokerServiceExporter();
exporter.setService(this.applicationContext.getBean(className));
exporter.setServiceInterface(clz);
exporter.afterPropertiesSet();
beanFactory.registerSingleton("/" + className, exporter);
}
}
private void hessian() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
HessianServiceExporter exporter = new HessianServiceExporter();
exporter.setService(this.applicationContext.getBean(className));
exporter.setServiceInterface(clz);
exporter.afterPropertiesSet();
beanFactory.registerSingleton("/" + className, exporter);
}
}
private void burlap() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
BurlapServiceExporter exporter = new BurlapServiceExporter();
exporter.setService(this.applicationContext.getBean(className));
exporter.setServiceInterface(clz);
exporter.afterPropertiesSet();
beanFactory.registerSingleton("/" + className, exporter);
}
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
}
3、客户端配置:
package com.plateno.util;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.remoting.caucho.BurlapProxyFactoryBean;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
public class BeanFactoryProxyClient implements BeanFactoryPostProcessor {
private ConfigurableListableBeanFactory beanFactory;
private String basePackage = "com.plateno.platform.service";
private String baseUrl = "http://localhost:9999/server/";
@Override
public void postProcessBeanFactory(
ConfigurableListableBeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
// httpInvoker();
// hessian();
burlap();
}
private void httpInvoker() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
HttpInvokerProxyFactoryBean factoryBean = new HttpInvokerProxyFactoryBean();
factoryBean.setServiceInterface(clz);
factoryBean.setServiceUrl(baseUrl + className);
factoryBean.afterPropertiesSet();
beanFactory.registerSingleton(className, factoryBean.getObject());
}
}
private void hessian() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
HessianProxyFactoryBean factoryBean = new HessianProxyFactoryBean();
factoryBean.setServiceInterface(clz);
factoryBean.setServiceUrl(baseUrl + className);
factoryBean.afterPropertiesSet();
beanFactory.registerSingleton(className, factoryBean.getObject());
}
}
private void burlap() {
ClassPathScanning scann = new ClassPathScanning(true);
scann.getClassFromPackage(basePackage);
List<String> classNameSet = scann.getClassNameSet();
List<Class<?>> clzSet = scann.getClzSet();
for(int i=0; i<classNameSet.size(); i++) {
Class<?> clz = clzSet.get(i);
String className = classNameSet.get(i);
BurlapProxyFactoryBean factoryBean = new BurlapProxyFactoryBean();
factoryBean.setServiceInterface(clz);
factoryBean.setServiceUrl(baseUrl + className);
factoryBean.afterPropertiesSet();
beanFactory.registerSingleton(className, factoryBean.getObject());
}
}
}
4、把服务端跟客户端配置在spring配置文件,然后程序就能用了,简化了很多。