原来spring的父子容器还可以这样用

前段时间写了个小组件 async-excel 为了异步导入导出公共组件化,由于整个流程需要做到将错误文件或者导出文件异步写到oss存储平台,并且需要让用户可查,所以这里还要设计一张表作为异步任务记录使用,但是又不想既有项目进行多数据源配置,那样对开发太不友好了。所以就想到了spring的父子容器。
父子容器的特性:

  • 子容器可以获取到父容器的bean
  • 父容器无法获取子容器的bean

利用这样的特性,我可以把数据源声明在子容器内。也就不影响原项目的配置了。

如何构建一个子容器呢?且看代码

protected AnnotationConfigApplicationContext createContext() {
//我们可以直接new一个出来
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//然后将配置类注册给它以及环境变量设置给他即可
        context.register(PropertyPlaceholderAutoConfiguration.class,
            this.defaultConfigType);
        
        context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
            this.propertySourceName,
            Collections.<String, Object>singletonMap(this.propertyName, this.contextName)));
        if (this.parent != null) {
            ExcelHandleBasePackages ehbp = this.parent.getBean(ExcelHandleBasePackages.class);
            basePackages = ehbp.getBasePackages();
       //将它设置为ApplicationContext的子容器     
            context.setParent(this.parent);
            context.setClassLoader(this.parent.getClassLoader());
        }
        context.setDisplayName(generateDisplayName(this.contextName));
        //最后执行refresh启动容器
        context.refresh();
        return context;
    }

一个子容器构建完成
然后要还需要提供个接口给外部获取bean,因为父容器无法获取子容器的bean
defaultConfigType 是作为配置的入口函数,就跟SpringbootApplication一样。作为配置入口就好了。

    public <T> T getInstance(Class<T> type) {
        AnnotationConfigApplicationContext context = getContext();
        //使用spring提供的工具类,可以从当前容器与祖先容器的所有bean中进行筛选。然父容器通过该方法获取Bean就好了
        if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context,
            type).length > 0) {
            return context.getBean(type);
        }
        return null;
    }

至此,又想到一个点,其实这也是之前微服务架构下特别头疼的一个问题,就是一些所谓的公共特性的服务,比如一些死的缓存类的东西,比如字典。以及一些配置,每次都要去调用公共服务,这太损耗性能以及开发成本太高了,如果可以直接使用一个子容器,将它包到各个服务去,并且提供一个公共数据源,将这部分高频,低效的内容高效化。有人也许会说,这样高耦合违背了微服务的设计原则。我也不反驳,这个就跟违背数据库范式一个原则,采取适当冗余,不要死读书。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值