hessian基于spring的自定义注解配置拓展(高效率开发hessian)

我们公司在已经上生产的应用里面,已经使用了hessian作为远程调用的组件使用。后期我们在做业务拓展的时候,做了很多hessian远程调用。

先来介绍一下我们公司hessian远程调用的开发流程:

1.在common中定义接口service。

2.在server端定义实现类,serviceImpl。

3在server端的xml里面定义serviceImpl的代理类。

4.在web.xml中定义servlet将hessian暴露到外部。

5.在client端的xml中定义serviceProxy,传入的参数包括在common中接口,以及server端的url。

6在client端配置中添加server端的url。 

开发人员在开发和维护的时候使用的是eclipse ,如果按照这种开发流程走的话,如果是想修改某个service的服务端的配置,我们打开文件查找器,输入hessian服务端xml名称,如果项目多的话会有多个,需要选择正确的一个。然后再打开service.java 拷贝名称 打开xml查找对应的bean。

总之一句话,使用xml配置,无论是开发还是维护还是比较繁琐的。


在来介绍一下我开发的hessian基于注解配置的开发流程:

1在common中定义service,并在service上写上注解;

2.在server端定义实现类,serviceImpl;

3.在client端需要使用的地方注入service;

4在properties文件中定义服务端的url;

如果需要修改bean的配置,只要ctrl+点击service找到注解就能完成修改。 虽然有些地方繁琐程度并没有减少,但是那些地方属于配置的范畴,随着业务的拓展维护的时间程度很低。

我认为如果使用hessian基于注解进行开发,开发效率会更高。


这里再介绍一下,hessian基于注解开发的要点,也是对spring深入探讨。

1.注解扫描

 

  private Set<BeanDefinition> findCandidateComponents(String basePackage, Class<?> annClass)
  {
    Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
    try {
      String packageSearchPath = "classpath*:" + resolveBasePackage(basePackage) + "/" + "**/*.class";

      Resource[] resources = resourcePatternResolver.getResources(packageSearchPath);
      for (Resource resource : resources) {
        if (resource.isReadable())
          try {
            MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(resource);
            ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
            sbd.setResource(resource);
            sbd.setSource(resource);

            GenericBeanDefinition definition = sbd;
            Class<?> entityClazz = Class.forName(definition.getBeanClassName());
            hessianService annotation = (hessianService)entityClazz.getAnnotation(hessianService.class);

            if (annotation != null)
              candidates.add(sbd);
          }
          catch (Throwable ex) {
            throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, ex);
          }
      }
    }
    catch (IOException ex)
    {
      throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
    }
    return candidates;
  }

2.bean xml定义,实现相关接口完成相关动作

bean必须实现接口

public class HessianServerBuilder
  implements InitializingBean{
  public void afterPropertiesSet() throws Exception { 			
          //在实例化完成后,在设置完预定义的属性之后该方法会被执行(无论是在xml中配置还是手动实例化bean都是同样的原则)
	}
}


3.手动实例化bean

 

	public void afterPropertiesSet() throws Exception {
		// 从spring上下文件获取到bean工厂
		DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) this.applicationContext
				.getAutowireCapableBeanFactory();
		// 扫描获取bean定义,这里得到的是包含 @hessianService 注解的service接口 的bean定义
		Set<BeanDefinition> candidateComponents = findCandidateComponents(this.basePackage, hessianService.class);
		for (BeanDefinition beanDefinition : candidateComponents)
			try {
				GenericBeanDefinition definition = (GenericBeanDefinition) beanDefinition;
				Class<?> serviceInterfaceClazz = Class.forName(definition.getBeanClassName());
				hessianService annotation = (hessianService) serviceInterfaceClazz.getAnnotation(hessianService.class);
				Object bean = null;
				try {
					bean = beanFactory.getBean(serviceInterfaceClazz);
				} catch (Exception e) {
					logger.info("创建hessian server 业务处理  bean时发生异常!");
					e.printStackTrace();
				}
				if (bean != null) {
					String beanName = annotation.id();
					if (StringUtils.isBlank(beanName)) {
						beanName = serviceInterfaceClazz.getSimpleName();
						beanName = beanName.substring(0, 1).toLowerCase() + beanName.substring(1);
					}
					if (!beanFactory.containsBean(beanName)) {
						BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
								.rootBeanDefinition(HessianServiceExporter.class);
						AbstractBeanDefinition beanProxyDefinition = beanDefinitionBuilder.getBeanDefinition();
						// 设置value就相当于在xml中设置 <property name="service"
						// ref="beanServiceName" />
						MutablePropertyValues propertyValues = new MutablePropertyValues();
						propertyValues.addPropertyValue("service", bean);
						propertyValues.addPropertyValue("serviceInterface", serviceInterfaceClazz);
						beanProxyDefinition.setPropertyValues(propertyValues);
						// 这一步是很关键的,如果beanFactory不是注册bean的 class 而是注册
						// bean的定义definition
						beanFactory.registerBeanDefinition("/" + beanName, beanProxyDefinition);
					} else {
						logger.debug("beanName:" + beanName + "对应的bean已经存在!");
					}
					logger.info("创建hessian server bean:" + beanName);
					try {
						// 这里就实例化生成了bean,如果不调用这个方法,那么如果bean在其他地方使用了,同样也是会被实例化的
						HessianServiceExporter hessianServiceExporter = beanFactory.getBean("/" + beanName,
								HessianServiceExporter.class);
						HessianBeanFactory.addSingle("/" + beanName, hessianServiceExporter);
					} catch (Exception e) {
						logger.info("创建hessian server bean:" + "/" + beanName + " 时发生异常!");
						e.printStackTrace();
					}
				}
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}

	}


后面再给出下载链接.骚等

下载hessian注解支持的maven工程


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值