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

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(){              ....          }        }  }

小米10微距镜头成像效果一塌糊涂,这到底是有多烂?小米10这颗微距镜头要参数没参数,要优化也没优化,成像效果更是一塌糊涂,还浪费手机有限的空间。说委婉一点叫凑数,说直接一点就一个字烂。小米10上的这颗200万的微距镜头到底差在哪些美国连遭黑客袭击!威胁食物供应,瘫痪石油管道,五角大楼都难逃这些黑客的网络攻击,可能是企图在美国引起恶性通货膨胀,从而摧毁我们的经济。当美国再度遭遇黑客袭击,全球最大的供应商JBS为了应对网络攻击,不得已的暂时关闭了运营。这带来直接的后果,人工智能机器学习和深度学习的区别是什么?先来一张图镇楼人工智能从广义上讲,人工智能描述一种机器与周围世界交互的各种方式。通过先进的像人类一样的智能软件和硬件结合的结果一台人工智能机器或设备就可以模仿人类的行为或像人一样执有没有智慧旅游景区方案参考?应为避暑胜地为宜!烈日当空照,山海花鸟游闲来万里游,醒来满目春!避暑之都来贵州农村,视频给你答案阿莎湖,湖两岸生活着不少苗族人民,晃如世外桃源,避暑胜地展溜村!要说智慧旅行,那对于腾讯副总裁孙忠怀批低智洗脑短视频像猪食,称公众场所外放像看傻子,你怎么看?这话没毛病!短视频江湖水很深!推荐算法就是冷冰冰的机器,根据你视频的点赞评论完播率等指标给你流量!短视频平台缺乏独立判断的用户基数庞大,自然这类短视频就播放量非常高!如此恶性循环,内涵字节后,腾讯副总裁称优酷是盗版起家,网友互相揭短没完了正观综合本届网络视听大会上,视频平台大乱斗在3日举办的第九届中国网络视听大会上,腾讯副总裁孙忠怀指出现在广泛出现的新兴盗版现象发源于十年前最早一代长视频网站,并举例优酷在十年前,优字节跳动发大事记怒批腾讯三年封禁近17次,还打了30余次官司6月4日下午,字节跳动在其官方微信上发了一篇字节跳动遭遇腾讯屏蔽和封禁大事记(20182021)的文章。文章中罗列了字节跳动在过去三年被腾讯封禁17次,而双方还打了30余次官司。字华为5G迎来反转,意大利做出高明选择,英国20亿英镑损失已成定局华为的发展正好印证了木秀于林,风必摧之这句话。在之前的竞争中,华为刚落脚美国市场,就被美国的思科盯上,当成最大的对手进行压制。即使如此,华为依旧靠实力在全球占据了不小的份额。在如今还真被任正非猜对了,台积电美国工厂正式开工了解更多科技资讯尽在圈聊科技。今天跟大家聊一聊还真被任正非猜对了,台积电美国工厂正式开工!在各种特殊手段的压制之下,美国在科技领域始终保持着绝对的领先优势,特别在于半导体领域,在国无限期推迟的华为P50,还剩多少期待文AI财经社吴迪编辑张泽应该春季发布的华为P50迟到了,但没有缺席。这是6月2日晚鸿蒙发布会上,华为消费者业务CEO余承东对外释放的信号。在这场发布会的最后,上市时间未定的华为P5听信美国教唆对华为出手,爱立信收到同等回击,市场将明显缩水美国前总统特朗普在任期间,先后对中国企业中兴和华为进行打击。尤其是华为,作为世界电信运营设备的巨头之一,华为的电信业务早已布局全球,在5G技术上更是遥遥领先,甚至已经与英国法国德国
质量可靠,天正电气入选浙江省级供应链创新与应用试点企业日前,浙江省商务厅等7部门联合发布通知,天正电气(605066。SH)成功入选第二批省级供应链创新与应用试点企业。据悉,省级供应链创新与应用试点期为两年,并同步建立试点绩效评估动态卡萨帝633冰箱,让生活充满诗情画意一个家最能体现一个人的生活态度和气质,所以在家装方面,我特别重视,希望能打造一个温馨自然,又简约的幸福之家。家的样子,是我们对生活的态度的体现。所以,在家电的选择上,我坚持自己的想佳能推出CJ17ex6。2B便携式4K广播级变焦镜头2021年4月8日,佳能(中国)有限公司宣布推出UHDgc系列便携式4K广播级变焦镜头CJ17e6。2B,适用于采用23型影像传感器的4K广播级摄像机,支持出色的4K光学性能,同时国产科技传来好消息!比亚迪不愧是全球最强的汽车企业之一要说论国产科技谁家最强,手机界必须要提及华米OV,汽车界必须要提及比亚迪。近日比亚迪官方公布了一个非常好的消息比亚迪新能源汽车在9月份的销量达到了惊人的70432辆,在全球新能源汽大国崛起,振奋人心!中国科技的又一张新名片诞生了历经中国顶尖科学家们数十年悉心打磨默默无闻地付出,从2008年我国自制的和谐号CRH3动车组在我国第一条高速铁路京津城际铁路正式投入运营,这也标志着我国铁路从此进入完全自主研制和在芯片上游传来好消息,武汉着力打造国家科技创新中心助力科技发展向往的武汉近日,有消息称华为麒麟9000库存已经消耗殆尽,台积电在2019年底为华为打造的高端芯片终于还是面临用完的险境,这其实也是老美扼杀中国高端芯片于摇篮的险恶用心。严峻的事实中国科技传来两大好消息震撼世界!航天科技与智慧城轨齐头并进要说国内可以引以为傲的科技,那所有人都会非航天莫属了,因为我国的航天事业都是我们自己靠自己,一步一个脚印地做出来的,没有依靠过国外的任何一个国家,所以我们掌握的航天科技都是自主安全中国路桥逢山开道,遇水搭桥,现在中国科技又有一张新名片当你被问到全球哪个国家的道路和桥梁建得最好做得最专业的问题的时候,我相信你脱口而出的国家就是我们中国!为什么呢?因为现在几乎所有中国人都知道我们国家在路桥建设上有一个光荣的称号基建国货再现智能黑科技,玻璃木质瓷砖都能爬,米粉真的拽不动兄弟们,今年的小米可真是太给力,不仅手机出货量在全球拿下了好名次,现在又要开始造车了,真的很难让人不激动。在小米6入坑了小米以后,对小米是刮目相看,现在总是喜欢时时刻刻的关注小米的5G助力智慧社会建设,飞利浦正式推出全新智能终端献礼时代会议5G的到来是网络世界一次革新化的象征,更快的传播速度将孕育更便捷高效的社会模式,在万物互联的当下,其影响力自然就不仅是局限于移动终端设备了。时代的脚步在前进透析当下,预见未来,飞利西安再添消费新地标国内首家京东MALL9月30日盛大开业9月30日,全国首家京东MALL在西安盛大开业。作为京东零售探索全渠道的新业态,京东MALL将为消费者带来线上线下融合的沉浸式购物体验,化身京东在线下的新潮产品展示中心用户体验互动