文档章节

把大象放进冰箱--spring自动扫描并发布rmi

Mr_Qi
 Mr_Qi
发布于 2016/10/08 22:21
字数 432
阅读 88
收藏 3
点赞 0
评论 0

对于需要暴露大量rmi的应用来说,每次新增加一个service都需要手写一段xml也是蛮累的……

偷懒的程序员想到了如下的办法

利用component-scan发布service同时发布rmi呢?

说做就做

把大象放进冰箱三步骤

  1. 打开冰箱门
    首先需要把所有的@service注解扫描,设置BeanDefinition的相关属性包括service,serviceName等
  2. 把大象塞进冰箱
    将BeanDefinition注册到spring容器中
  3. 关上冰箱门
    初始化对应的BeanDefinition


    具体代码如下

    /**
     * Created by qixiaobo on 2016/10/8.
     */
    public class PublishRmiBean implements ApplicationContextAware {
        private Logger logger = Logger.getLogger(PublishRmiBean.class);
        private String basePkg;
        private ApplicationContext context;
        private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        @Value("${erp.rmi.base.port}")
        private int port;
     
        private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
     
        private static final List<TypeFilter> includeFilters = new LinkedList<>();
        private static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
     
     
        public String getBasePkg() {
            return basePkg;
        }
     
        public void setBasePkg(String basePkg) {
            this.basePkg = basePkg;
        }
     
        static {
            includeFilters.add(new AnnotationTypeFilter(Service.class));
        }
     
        @PostConstruct
        public void init() throws IOException {
            assert (basePkg != null);
            String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    resolveBasePackage(basePkg) + "/" + DEFAULT_RESOURCE_PATTERN;
            Resource[] resources = this.resourcePatternResolver.getResources(packageSearchPath);
            for (Resource resource : resources) {
                {
                    try {
                        MetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(resource);
                        if (isCandidateComponent(metadataReader)) {
                            ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
                            sbd.setResource(resource);
                            sbd.setSource(resource);
                            if (isCandidateComponent(sbd)) {
                                String clazzName = sbd.getBeanClassName();
                                Class clazz = null;
                                if (sbd.hasBeanClass()) {
                                    clazz = sbd.getBeanClass();
                                } else {
                                    clazz = Class.forName(clazzName);
                                }
                                String beanName = RmiNameGenerator.getBeanName(clazzName.substring(clazzName.lastIndexOf(".") + 1));
                                registerRmi(clazz, beanName);
                            }
                        }
                    } catch (Throwable e) {
                        logger.error(e);
                    }
                }
            }
            try {
                context.getBeansOfType(RmiServiceExporter.class);
            } catch (Exception ex) {
                logger.error(ex);
            }
     
        }
     
        private void registerRmi(Class clazz, String beanName) {
            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RmiServiceExporter.class);
            if (clazz.getInterfaces().length == 0) {
                logger.warn("skip publish rmi:" + beanName + " because no interface found!");
                return;
            }
            builder.addPropertyValue("serviceInterface", clazz.getInterfaces()[0]);
            builder.addPropertyValue("serviceName", beanName);
            builder.addPropertyValue("registryPort", port);
            builder.addPropertyReference("remoteInvocationExecutor", "clientInfoRemoteInvocationExecutor");
            builder.addPropertyValue("service", context.getBean(clazz));
            builder.setLazyInit(false);
            getBeanDefinitionRegistry().registerBeanDefinition(beanName + "Exporter", builder.getRawBeanDefinition());
            logger.info("publish rmi:" + beanName);
        }
     
     
        private BeanDefinitionRegistry getBeanDefinitionRegistry() {
            return (BeanDefinitionRegistry) ((XmlWebApplicationContext) context).getBeanFactory();
        }
     
        private boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
            for (TypeFilter tf : includeFilters) {
                if (tf.match(metadataReader, this.metadataReaderFactory)) {
                    return true;
                }
            }
            return false;
        }
     
        private boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
            return (beanDefinition.getMetadata().isConcrete() && beanDefinition.getMetadata().isIndependent());
        }
     
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            this.context = applicationContext;
        }
     
        private String resolveBasePackage(String basePackage) {
            return ClassUtils.convertClassNameToResourcePath(basePackage);
        }
     
    }

    在spring的xml中注册如下

    <bean class="com.xxx.PublishRmiBean" >
        <property name="basePkg" value="com.xxx.service.*.impl"/>
    </bean>

     

© 著作权归作者所有

共有 人打赏支持
Mr_Qi
粉丝 251
博文 298
码字总数 312931
作品 0
南京
程序员
大象放进冰箱 - 建造者模式

设计模式 - 建造者模式 [toc] 简介 Builder:又名生产器模式 将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 精髓:顺序 组成角色 builder:给出一个抽象接口...

草帽行者 ⋅ 2016/05/10 ⋅ 0

架构与设计

虽然我其实在软件这个行业里面也干了不少的年头了,但是回想起来其实很多时候都在从事一些很“粗浅”的工作。因为那个时候虽然在不停的写程序,但根本不知道什么是对的,什么是好的。所以,人...

崔钢 ⋅ 2013/07/25 ⋅ 8

PHP 面向对象实例:获取数据库用户数据

我们使用面向过程的方式和面向对象的方式分别写几个程序,理解面向对象编程带来的优势。 数据库使用mysql 数据库, 数据库结构和数据如下图所示。 先写一个数据库配置文件如下: db_config....

BENNEE ⋅ 2011/03/22 ⋅ 0

spring梳理(二) 基于注解的方式注册bean

我们知道,如果想要将bean交由spring容器管理,就需要首先将bean注册在spring容器中,而bean可以通过xml或者注解的方式进行注册,基于xml的配置一般是通过、等xml标签进行配置,然后由sprin...

wyn_lin ⋅ 05/25 ⋅ 0

Spring使用ComponentScan扫描Maven多模块工程的其它模块

说明:在新建好了Maven多模块工程后,如果想要在其它模块也能使用Spring的对象管理,比如@Autowrited这些注入方式,那么就必须开启包扫描的功能才能使其进行注入到Spring的对象管理中。 解决...

easonjim ⋅ 01/20 ⋅ 0

Mybatis spring and mybatis and mybatis-springboot-starter

Mybatis spring and mybatis and mybatis-springboot-starter 这篇博文主要涉及到的是mybatis是怎么集成到spring已经spring boot的,有关mybatis的用法及其自身的源码 设计,我会到开另一个文...

来福马斯特 ⋅ 04/25 ⋅ 0

《Spring技术内幕》学习笔记18——Spring使用Hessian实现远程调用

Spring目前提供了对RMI、 HttpInvoker、Hessian、Burlap及WebService等Remoting技术的集成。Spring屏蔽了这些实现技术的差异,用户只需开发简单的Java对象(Plain Old Java Objects,POJO)然后...

谜男amu ⋅ 05/16 ⋅ 0

扯扯Spring的IoC

如果有不对之处,望斧正,因为我学习的过程中看的很多资料之间确实存在一点矛盾,可能有的东西我在学习时理解错了。 有人说DI(依赖注入)就是IoC(控制反转),其实这么说也没错,就像韩国人就是...

天地一MADAO_ ⋅ 2014/04/05 ⋅ 5

4.1 面向对象思想概述和举例

1:面向对象思想 面向对象是基于面向过程的编程思想。 面向过程:强调的是每一个功能的步骤 面向对象:强调的是对象,然后由对象去调用功能 2:面向对象的思想特点 A:是一种更符合我们思想习惯...

msirene ⋅ 2015/09/04 ⋅ 0

Redis作者谈Redis应用场景

毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多变的数据结构和数据操作,为不...

chaoluo001 ⋅ 2017/07/06 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Java Web如何操作Cookie的添加修改和删除

创建Cookie对象 Cookie cookie = new Cookie("id", "1"); 修改Cookie值 cookie.setValue("2"); 设置Cookie有效期和删除Cookie cookie.setMaxAge(24*60*60); // Cookie有效时间 co......

二营长意大利炮 ⋅ 今天 ⋅ 0

【每天一个JQuery特效】淡入淡出显示或隐藏窗口

我是JQuery新手爱好者,有时间就练练代码,防止手生,争取每天一个JQuery练习,在这个博客记录下学习的笔记。 本特效主要采用fadeIn()和fadeOut()方法显示淡入淡出的显示效果显示或隐藏元...

Rhymo-Wu ⋅ 今天 ⋅ 0

Spring JDBC使用方法

普通实现: 1、创建数据表customer。 可以使用任何数据库实现,在项目中要引入相应数据库驱动包并配置相应数据库连接。 2、创建Customer pojo。 Customer类的属性对应数据库的属性,除了为每...

霍淇滨 ⋅ 今天 ⋅ 0

Contos 7 安装Jenkins

Jenkins是一款能提高效率的软件,它能帮你把软件开发过程形成工作流,典型的工作流包括以下几个步骤 开发 提交 编译 测试 发布 有了Jenkins的帮助,在这5步中,除了第1步,后续的4步都是自动...

欧虞山 ⋅ 今天 ⋅ 0

revel

revel install go get github.com/revel/revelgo get github.com/revel/cmd create new app revel new git.oschina.net/zdglf/myapp run app revel run git.oschina.net/zdglf/myapp ot......

zdglf ⋅ 今天 ⋅ 0

49. Group Anagrams - LeetCode

Question 49. Group Anagrams Solution 思路:维护一个map,key是输入数组中的字符串(根据字符排好序) Java实现: public List<List<String>> groupAnagrams(String[] strs) { Map<Strin......

yysue ⋅ 今天 ⋅ 0

spring Email

使用spring发Email其实就是使用spring自己封装携带的一个javamail.JavaMailSenderImpl类而已。这个类可以当一个普通的java对象来使用,也可以通过把它配置变成spring Bean的方式然后注入使用...

BobwithB ⋅ 今天 ⋅ 0

spark 整理的一些知识

Spark 知识点 请描述spark RDD原理与特征? RDD全称是resilient distributed dataset(具有弹性的分布式数据集)。一个RDD仅仅是一个分布式的元素集合。在Spark中,所有工作都表示为创建新的...

tuoleisi77 ⋅ 今天 ⋅ 0

思考

时间一天天过感觉自己有在成长吗?最怕的是时光匆匆而过,自己没有收获!下面总结下最近自己的思考。 认识自己 认识另一个自己,人们常说要虚心听取别人意见和建议。然而人往往是很难做到的,...

hello_hp ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部