spring通過註解自動暴露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

  • 客戶端聲明與調用
  
 
 http://localhost:8080/Hello/helloService
 
  
 
 com.test.hello.service.HelloService
 

調用

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());
 }
 }
}


分享到:


相關文章: