范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Spring下动态注册和获取Bean

  有时候需要在运行时动态注册Bean到Spring容器,并根据名称获取注册的Bean。比如我们自己的SAAS架构的系统需要调用ThingsBoard API和Thingsboard交互,就可以通过ThingsBoard提供的RestClient工具类。但这要求每个租户使用自己唯一的RestClient,为了达到此目的,系统启动时需要将每个租户的RestClient加载到Spring容器中以供租户随时使用,另外系统管理员可以在系统中随时创建新的租户,因此就需要在系统启动后运行过程随时可以注册新的RestClient到Spring容器中。
  下面从运行时手动注册Bean到Spring容器以及从Spring容器中获取容器管理的Bean入手进行介绍。 运行时注册Bean到Spring容器
  访问接口  /**       * 注册bean到Spring容器。使用构造函数参数初始化bean。       * 备注:需要有默认构造器,即需要有无参构造器。       * @param beanName       * @param clazz       * @param constructorArgs       */      public static void registerBean(String beanName, Class<?> clazz, Object... constructorArgs) {          registerBean(beanName, clazz, new InitBean() {              @Override              public void init(BeanDefinitionBuilder beanDefinitionBuilder) {                  log.info("使用构造函数参数初始化class[{}]",clazz);                  if(constructorArgs!=null&&constructorArgs.length>0){                      for (Object constructorArg : constructorArgs) {                          beanDefinitionBuilder.addConstructorArgValue(constructorArg);                      }                  }              }          });      }          /**       * 注册bean到spring容器中。使用属性参数初始化bean。       * @param beanName 名称       * @param clazz    class       */      public static void registerBean(String beanName, Class<?> clazz, Map propertyValueMap) {         registerBean(beanName, clazz, new InitBean() {             @Override             public void init(BeanDefinitionBuilder beanDefinitionBuilder) {                 log.info("使用属性参数初始化class[{}]",clazz);                 if(propertyValueMap!=null){                     propertyValueMap.forEach((k,v)->{                         beanDefinitionBuilder.addPropertyValue(k, v);                     });                 }             }         });      }
  核心代码:      private static void registerBean(String beanName, Class<?> clazz, InitBean initBean) {          // 1. 检查是否存在重名的bean,如果存在打印警告日志,并且返回,          if (defaultListableBeanFactory.containsBean(beanName)) {              log.warn("The Bean  [{}] for  type [{}] is already exists. Please check.", beanName, clazz.getName());              return;          }          // 2. 通过BeanDefinitionBuilder创建bean定义          BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);            //3. 初始化Bean          if (initBean != null) {              initBean.init(beanDefinitionBuilder);          }            // 4. 注册bean          defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getRawBeanDefinition());          log.info("register bean [{}],Class [{}] success.", beanName, clazz);      }
  由于初始化Bean有2重方式,一种是设置Property的方式(必须有默认的构造函数),一种是构造函数的方式,为了避免重复的代码特写了回调类 InitBean      public interface InitBean{          void init( BeanDefinitionBuilder beanDefinitionBuilder);      }
  ApplicationContext和DefaultListableBeanFactory的获取  @Slf4j  public class SpringContextUtil implements ApplicationContextAware {      private static ApplicationContext applicationContext = null;      private static DefaultListableBeanFactory defaultListableBeanFactory;        @Override      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {          if (SpringContextUtil.applicationContext == null) {              SpringContextUtil.applicationContext = applicationContext;          }          //将applicationContext转换为ConfigurableApplicationContext          ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) applicationContext;          // 获取bean工厂并转换为DefaultListableBeanFactory          this.defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();          log.info("init ApplicationContext and  BeanFactory Success.");      }      ....Bean从Spring容器中的动态获取
  提供三种方式从Spring 容器中获取bean,分别是根据bean的名称,bean的class类型(bean是gingleton的)根据bean的名称以及class类型。      public static Object getBean(String name) {          return getApplicationContext().getBean(name);      }        public static  T getBean(Class clazz) {          return getApplicationContext().getBean(clazz);      }        public static  T getBean(String name, Class clazz) {          return getApplicationContext().getBean(name, clazz);      }
  如上,使用如上介绍的注册和获取Bean的方式就可以轻松获得,运行时动态注册和获取Bean的能力。
  备注:在SpringBoot微服务启动时手动完成Bean的注册可以利用SpringBoot的提供的 org.springframework.CommandLineRunner或者  org.springframework.bootApplicationRunner`
  参考示例:  @Component  @Slf4j  public class TenantRestClientInit implements CommandLineRunner {           @Override      public void run(String... args) throws Exception {          initSomeThings();      }        private void initSomeThings(){              ....          }        }  }

民间没有真藏品,但有艺术品,你认同吗?本人不认同!本人拿出来东西都可是国宝级的文物!这下面可是元代笔架山,价位在两百万以上。国拍定价为两百万!因为起拍价只有50万。所以本人拒绝上拍!这可是福字碗!随便拿出来一件都不差!联通5G支持云合唱每个三亿分之一点燃冰雪激情共赴冬奥之约这个新年,是冬奥味儿的。每个三亿分之一,旋转奔跑画个圈中国联通冬奥加油歌每个三亿分之一正在祖国大地的每一个角落被传唱,用歌声点燃冬奥激情,迎接冰雪之约。作为北京2022年冬奥会唯一推进新能源汽车发展,2022年将有哪些举措?新华社北京1月31日电题推进新能源汽车发展,2022年将有哪些举措?新华社记者张辛欣工信部近日发布数据显示,2021年,我国新能源汽车发展迅猛,产销量均超过350万辆,同比增长1。新春走基层农民网上卖年货备年货渐成风尚来源新华网寒冬腊月,随着百誉智能物流专车的到来,湖北省宜昌市长阳土家族自治县都镇湾镇响石村村民易发元在村里的快递物流服务站,收到了孩子从广东省珠海市寄回来的年货包裹,易发元的背篓里Python机器学习(五十四)SciPyk均值聚类聚类(Kmeansclustering)是在一组未标记的数据中,将相似的数据(点)归到同一个类别中的方法。聚类与分类的最大不同在于分类的目标事先已知,而聚类则不知道。Kmeans是19岁大学生拒绝被马斯克收买特斯拉(TSLA。US)CEO埃隆马斯克曾向19岁大学生杰克斯威尼(JackSweeney)出价5000美元,希望后者关闭追踪其私人飞机的推特账号。斯威尼称,他拒绝了马斯克的出价,聊聊电商与实体看到很多人都说实体贵,态度差,都说电商好。其实消费者的选择都没法干预,但是这样的电商发展趋势,已经不是消费者的选择那么简单了。电商是极端的压榨中间环节,最后压榨生产商,其实最后能生Docker部署PythonWeb服务Python项目目录结构dirapp。py。dirWeb项目根目录app。pyflasktornado之类Web框架写好的Web服务方案一编写Dockerfiledockercom超级果冻材料可在汽车碾压后幸存下来英国剑桥大学研究人员开发了一种柔软而坚固的新材料,外观和感觉就像软软的果冻,但其可承受相当于大象站在上面的重量,在压缩时就像一块超硬防碎的玻璃。其还可完全恢复到原来的形状,即使其8将以中航锂电替换宁德时代?小鹏汽车回应与事实有巨大出入澎湃新闻记者吴遇利1月30日,针对欣旺达将作为小鹏G9某一版本的A供及将宁德时代逐步替换为中航锂电(已更名为中创新航)的传言,小鹏汽车方面对澎湃新闻记者回应称,近日外面传播的我们要IPCC评估报告系列解读海洋环流的长期变化和预估俞永强相比之前的评估报告,联合国政府间气候变化专门委员会(IPCC)第一工作组第六次评估报告气候变化2021自然科学基础进一步确认了人类活动对海洋环流的影响,并基于最新的数值模式给
秋季雨后树叶落在车上,对车子有哪些损害?进入十月份,一场秋雨一场凉,不少车主已经看到自己爱车上落上了不少树叶,不要只顾着欣赏秋景,快看看这些树叶是否有树胶。很多树木的树胶会黏在树叶上,如果伴随着秋雨一同落在车身上,那车主路面积水不可怕,涉水熄火才可怕暴雨天遇到路面积水?郊区野游遇见涉水路段?这时,驾驶汽车需要注意什么呢?当我们遇到积水路面,应该减速或停车观察路面积水情况,若水位没有达到保险杠或轮胎的三分之二,表示可以匀速缓慢的国庆自驾归来你给爱车做检查和养护了吗?不知不觉国庆小长假就结束了,这个假期大家都去哪里玩了呢?就当前疫情形式来看,更多的朋友会选择自驾游,方便省钱还安全,而且国庆还有高速免费政策,综合下来,节日自驾游的性价比太高了,所为何考科二挂科概率高?这三点原因绕不开很多人考驾照都是几经波折的,很少有人可以一把过,除了纯理论知识的科目一,最难考的就是科目二,在科目二上挂科,下面几点是很多新手绕不开的通病。首先就是心态问题,许多人在考试的时候会紧车胎多久换一次?这三个换胎信号要记住一般来说,当汽车行驶3万公里至5万公里期间,轮胎就需要更换,理论上软胎8年更换一次,硬胎5年更换一次,具体的更换时间则是要看实际的路况和行驶里程。当然,是否需要换胎还是需要通过观察高速常见的几种标线,走错就扣三分罚款二百为了保障行驶安全,许多道路上都会设计各种标线,尤其是高速公路,如果遇到下面几种标线,一定要认识。首先是最常见的导流线,高速公路的匝道附近都会有分布,它额造型特殊,车辆不可以压线行驶自动挡车相当于玩具车?只会D挡绝对不行很多小伙伴喜欢自动挡的汽车,因为自动挡汽车没有离合器,也无需反复挂挡,几乎是踩油就能走,操作非常简单,最容易上手。虽然自动挡汽车堪称是玩具车,动挡操作也堪称是傻瓜操作,但自动挡汽车马自达与出租车禁止入内?此马自达非彼马自达马自达在国内的销量一直是不温不火的,今年凭借南北马自达合并一事上过几次热搜,如今马自达合并事宜已暂时告一段落,马自达也在稳步的发展中。马自达造车有着自己独特的见解和坚持,所以很难在米其林造个轮胎,竟然不需要充气最近米其林重新发明了一种防爆胎的车轮,它叫做UPTIS,因为它不需要填充气体,所以就自然不会被戳破,也就不会出现爆胎的情况。这款轮胎的制造材料以复合橡胶和树脂嵌入式玻璃纤维的混合材在国内纵横十年,现代瑞纳凭何火了这么久?现代瑞纳在近期迎来了上市,1。4L手动焕新版最低配车型低至4。99w,自动跃劲顶配版价格也仅为7。39w,作为一款合资品牌三厢车,价格是非常低的。2020款北京现代瑞纳保持了上一代合资车的配置国产车的售价,大众七座SUV值得一看大众斯柯达迪亚克是一款来自于大众MQB平台的中型SUV,科迪亚克于2019年正式上市,与全新大众途观L来自于同一平台大众。TSI3305座标准版最低配车型指导价格为18。99w,T