经过注解自动暴露Hessian服务
通过注解自动暴露Hessian服务
一、Hessian与spring集成
Hessian可以与spring完美无缝的集成,我们先来看一下如何集成:
服务端服务暴露
以上使用spring在代码配置声明bean的方式暴露了一个hession服务:http://localhost:8080/Hello/helloService
客户端声明与调用
声明
调用
二、存在的问题
上述的方法是最常用的集成方式,但存在一个问题,如果我们现在要在服务端暴露另外一个服务,那么需要添加如下代码:
如果再来一个服务呢,那我们就再添加类似的代码,能不能不重复添加这些类似的暴露代码呢?
三、使用注解自动暴露服务
首先,新建一个叫HessianService的注解类,注意这个注解类包含了spring的Service注解
接着,我们把原先用@Service注解的服务类换成@HessianService
然后,我们使用spring的BeanFactoryPostProcessor机制,动态暴露hessian服务
一、Hessian与spring集成
Hessian可以与spring完美无缝的集成,我们先来看一下如何集成:
服务端服务暴露
@Autowired private HelloService helloService; @Bean(name = "/helloService") public HessianServiceExporter exportHelloService() { HessianServiceExporter exporter = new HessianServiceExporter(); exporter.setService(helloService); exporter.setServiceInterface(HelloService .class); return exporter; }
以上使用spring在代码配置声明bean的方式暴露了一个hession服务:http://localhost:8080/Hello/helloService
客户端声明与调用
声明
<bean id="studentService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean"> <!-- 请求代理Servlet路径 --> <property name="serviceUrl"> <value>http://localhost:8080/Hello/helloService</value> </property> <!-- 接口定义 --> <property name="serviceInterface"> <value>com.test.hello.service.HelloService</value> </property> </bean>
调用
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/spring/ApplicationContext.xml"); HelloService helloService = (HelloService) context.getBean("helloService"); helloService.sayHi("hi, i am client");
二、存在的问题
上述的方法是最常用的集成方式,但存在一个问题,如果我们现在要在服务端暴露另外一个服务,那么需要添加如下代码:
@Autowired private AnotherService1 anotherService; @Bean(name = "/anotherService") public HessianServiceExporter exportAnotherService() { HessianServiceExporter exporter = new HessianServiceExporter(); exporter.setService(anotherService); exporter.setServiceInterface(AnotherService .class); return exporter; }
如果再来一个服务呢,那我们就再添加类似的代码,能不能不重复添加这些类似的暴露代码呢?
三、使用注解自动暴露服务
首先,新建一个叫HessianService的注解类,注意这个注解类包含了spring的Service注解
import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.springframework.stereotype.Service; @Target({ java.lang.annotation.ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Documented @Service public @interface HessianService { public abstract String value() default ""; }
接着,我们把原先用@Service注解的服务类换成@HessianService
@HessianService public class HelloServiceImpl implements HelloService { ... ... }
然后,我们使用spring的BeanFactoryPostProcessor机制,动态暴露hessian服务
@Component public class HessianServiceScanner implements BeanFactoryPostProcessor { public void postProcessBeanFactory( ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] beanNames = beanFactory .getBeanNamesForAnnotation(HessianService.class); for (String beanName : beanNames) { String className = beanFactory.getBeanDefinition(beanName) .getBeanClassName(); Class<?> clasz = null; try { clasz = Class.forName(className); } catch (ClassNotFoundException e) { throw new BeanInitializationException(e.getMessage(), e); } String hessianServiceBeanName = "/" + beanName.replace("Impl", ""); BeanDefinitionBuilder builder = BeanDefinitionBuilder .rootBeanDefinition(HessianServiceExporter.class); builder.addPropertyReference("service", beanName); builder.addPropertyValue("serviceInterface", clasz.getInterfaces()[0].getName()); ((BeanDefinitionRegistry) beanFactory).registerBeanDefinition( hessianServiceBeanName, builder.getBeanDefinition()); } } }