专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

SpringBoot中Import三种使用方式

  转载于:公众号:后端元宇宙
  需要注意的是:ImportSelector、ImportBeanDefinitionRegistrar这两个接口都必须依赖于Im
  port一起使用,而Import可以单独使用。
  Import是一个非常有用的注解,它的长处在于你可以通过配置来控制是否注入该Bean,也可以通过条件来控制注入哪些Bean到Spring容器中。
  比如我们熟悉的:EnableAsync、EnableCaching、EnableScheduling等等统一采用的都是借助Import注解来实现的。
  下面我们就通过示例来了解Import三种用法!一、引入普通类
  有个用户类如下DatapublicclassUserConfig{用户名privateStringusername;手机号privateStringphone;}
  那么如何通过Import注入容器呢?Import(UserConfig。class)ConfigurationpublicclassUserConfiguration{}
  当在Configuration标注的类上使用Import引入了一个类后,就会把该类注入容器中。
  当然除了Configuration比如Component、Service等一样也可以。
  测试SpringBootTestRunWith(SpringRunner。class)publicclassUserServiceTest{AutowiredprivateUserConfiguserConfig;TestpublicvoidgetUser(){StringnameuserConfig。getClass()。getName();System。out。println(namename);}}
  控制台输出namecom。jincou。importselector。model。UserConfig
  如果Import的功能仅仅是这样,那其实它并没什么特别的价值,我们可以通过其它方式实现?ConfigurationpublicclassUserConfiguration{BeanpublicUserConfiguserConfig(){returnnewUserConfig();}}
  再比如直接添加Configuration注解ConfigurationpublicclassUserConfig{。。。。。。}
  确实如果注入静态的Bean到容器中,那完全可以用上面的方式代替,但如果需要动态的带有逻辑性的注入Bean,那才更能体现Import的价值。
  二、引入ImportSelector的实现类
  说到ImportSelector这个接口就不得不说这里面最重要的一个方法:selectImports()。publicinterfaceImportSelector{String〔〕selectImports(AnnotationMetadataimportingClassMetadata);}
  这个方法的返回值是一个字符串数组,只要在配置类被引用了,这里返回的字符串数组中的类名就会被Spring容器new出来,然后再把这些对象注入IOC容器中。
  所以这有啥用呢?我们还是用一个例子演示一下。1、静态import场景(注入已知的类)
  我们先将上面的示例改造下:
  自定义MyImportSelector实现ImportSelector接口,重写selectImports方法publicclassMyImportSelectorimplementsImportSelector{OverridepublicString〔〕selectImports(AnnotationMetadataimportingClassMetadata){这里目的是将UserConfig注入容器中returnnewString〔〕{com。jincou。importselector。model。UserConfig};}}
  然后在配置类引用Import(MyImportSelector。class)ConfigurationpublicclassUserConfiguration{}
  这样一来同样可以通过成功将UserConfig注入容器中。
  如果看到这,你肯定会有疑问。我这又是新建MyImportSelector类,又是实现ImportSelector重写selectImports方法,然后我这么做有个卵用呢?
  直接把类上加个Component注入进去不香吗?这个ImportSelector把简单的功能搞这么复杂。
  接下来就要说说如何动态注入Bean了。2、动态import场景(注入指定条件的类)
  我们来思考一种场景,就是你想通过开关来控制是否注入该Bean,或者说通过配置来控制注入哪些Bean,这个时候就有了ImportSelector的用武之地了。
  我们来举个例子,通过ImportSelector的使用实现条件选择是注入本地缓存还是Redis缓存。
  1)、定义缓存接口和实现类
  顶层接口publicinterfaceCacheService{voidsetData(Stringkey);}
  本地缓存实现类publicclassLocalServicemplimplementsCacheService{OverridepublicvoidsetData(Stringkey){System。out。println(本地存储存储数据成功keykey);}}
  redis缓存实现类publicclassRedisServicemplimplementsCacheService{OverridepublicvoidsetData(Stringkey){System。out。println(redis存储数据成功keykey);}}
  2)、定义ImportSelector实现类
  以下代码中根据EnableMyCache注解中的不同值来切换缓存的实现类再spring中的注册。publicclassMyCacheSelectorimplementsImportSelector{OverridepublicString〔〕selectImports(AnnotationMetadataimportingClassMetadata){MapString,ObjectannotationAttributesimportingClassMetadata。getAnnotationAttributes(EnableMyCache。class。getName());通过不同type注入不同的缓存到容器中CacheTypetype(CacheType)annotationAttributes。get(type);switch(type){caseLOCAL:{returnnewString〔〕{LocalServicempl。class。getName()};}caseREDIS:{returnnewString〔〕{RedisServicempl。class。getName()};}default:{thrownewRuntimeException(MessageFormat。format(unsupportcachetype{0},type。toString()));}}}}
  3)、定义注解
  EnableMyCache注解就像一个开关,通过这个开关来是否将特定的Bean注入容器。
  定义一个枚举Target(ElementType。TYPE)Retention(RetentionPolicy。RUNTIME)DocumentedImport(MyCacheSelector。class)publicinterfaceEnableMyCache{CacheTypetype()defaultCacheType。REDIS;}publicenumCacheType{LOCAL,REDIS;}
  4)、测试
  这里选择本地缓存。EnableMyCache(typeCacheType。LOCAL)SpringBootTestRunWith(SpringRunner。class)publicclassUserServiceTest{AutowiredprivateCacheServicecacheService;Testpublicvoidtest(){cacheService。setData(key);}}
  控制台输出本地存储存储数据成功keykey
  切换成redis缓存EnableMyCache(typeCacheType。REDIS)SpringBootTestRunWith(SpringRunner。class)publicclassUserServiceTest{AutowiredprivateCacheServicecacheService;Testpublicvoidtest(){cacheService。setData(key);}}
  控制台输出redis存储数据成功keykey
  这个示例不是就是Bean的动态注入了吗?3、Spring如何使用ImportSelector的场景
  SpringBoot有两个常用注解EnableAsyncEnableCaching其实就是通过ImportSelector来动态注入Bean
  看下EnableAsync注解,它有通过Import({AsyncConfigurationSelector。class})Target({ElementType。TYPE})Retention(RetentionPolicy。RUNTIME)DocumentedImport({AsyncConfigurationSelector。class})publicinterfaceEnableAsync{Classlt;?extendsAnnotationannotation()defaultAnnotation。class;booleanproxyTargetClass()defaultfalse;AdviceModemode()defaultAdviceMode。PROXY;intorder()default2147483647;}
  AsyncConfigurationSelector。classpublicclassAsyncConfigurationSelectorextendsAdviceModeImportSelectorEnableAsync{privatestaticfinalStringASYNCEXECUTIONASPECTCONFIGURATIONCLASSNAMEorg。springframework。scheduling。aspectj。AspectJAsyncConfiguration;publicAsyncConfigurationSelector(){}NullablepublicString〔〕selectImports(AdviceModeadviceMode){switch(adviceMode){casePROXY:returnnewString〔〕{ProxyAsyncConfiguration。class。getName()};caseASPECTJ:returnnewString〔〕{org。springframework。scheduling。aspectj。AspectJAsyncConfiguration};default:returnnull;}}}
  是不是和我上面写的示例一样。
  总之,向这种还不能决定去注入哪个处理器(如果你能决定,那就直接Import那个类好了,没必要实现接口了),就可以实现此接口,写出一些判断逻辑,不同的配置情况注入不同的处理类。
  三、引入ImportBeanDefinitionRegister的实现类
  当配置类实现了ImportBeanDefinitionRegistrar接口,你就可以自定义往容器中注册想注入的Bean。
  这个接口相比与ImportSelector接口的主要区别就是,ImportSelector接口是返回一个类,你不能对这个类进行任何操作,但是ImportBeanDefinitionRegistrar是可以自己注入BeanDefinition,可以添加属性之类的。publicclassMyImportBeanimplementsImportBeanDefinitionRegistrar{paramimportingClassMetadata当前类的注解信息paramregistry注册类,其registerBeanDefinition()可以注册beanOverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){}}1、举一个简单的示例
  我们通过先通过一个简单的小示例,来理解它的基本使用
  假设有个用户配置类如下DatapublicclassUserConfig{用户名privateStringusername;手机号privateStringphone;}
  我们通过实现ImportBeanDefinitionRegistrar的方式来完成注入。publicclassMyImportBeanimplementsImportBeanDefinitionRegistrar{paramimportingClassMetadata当前类的注解信息paramregistry注册类,其registerBeanDefinition()可以注册beanOverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){构建一个BeanDefinition,Bean的类型为UserConfig,这个Bean的属性username的值为后端元宇宙AbstractBeanDefinitionbeanDefinitionBeanDefinitionBuilder。rootBeanDefinition(UserConfig。class)。addPropertyValue(username,后端元宇宙)。getBeanDefinition();把UserConfig这个Bean的定义注册到容器中registry。registerBeanDefinition(userConfig,beanDefinition);}}
  通过配置类中引入MyImportBean对象。Import(MyImportBean。class)ConfigurationpublicclassUserImportConfiguration{}
  我们再来测试下EnableMyCache(typeCacheType。REDIS)SpringBootTestRunWith(SpringRunner。class)publicclassUserServiceTest{AutowiredprivateUserConfiguserConfig;Testpublicvoidtest(){StringusernameuserConfig。getUsername();System。out。println(usernameusername);}}
  控制台输出username后端元宇宙
  说明通过ImportBeanDefinitionRegistrar方式,已经把UserConfig注入容器成功,而且还为给bean设置了新属性。
  然后我们再来思考一个问题,就比如我们在其它地方已经将UserConfig注入容器,这里会不会出现冲突,或者不冲突的情况下,属性能不能设置成功?
  我们来试下Import(MyImportBean。class)ConfigurationpublicclassUserImportConfiguration{这里通过Bean注解,将UserConfig注入Spring容器中,而且名称也叫userConfigBeanpublicUserConfiguserConfig(){returnnewUserConfig();}}
  然后我们再来跑下上面的测试用例,发现报错了。
  2、举一个复杂点的例子
  Mybatis的MapperScan就是用这种方式实现的,MapperScan注解,指定basePackages,扫描MybatisMapper接口类注入到容器中。
  这里我们自定义一个注解MyMapperScan来扫描包路径下所以带MapperBean注解的类,并将它们注入到IOC容器中。
  1)、先定义一个MapperBean注解,就相当于我们的Mapper注解定义包路径。(指定包下所有添加了MapperBean注解的类作为bean)注意这里Import(MyMapperScanImportBean。class)的使用Retention(RetentionPolicy。RUNTIME)Target(ElementType。TYPE)DocumentedpublicinterfaceMapperBean{}
  2)、一个需要注入的bean,这里加上MapperBean注解。packagecom。jincou。importselector。mapperScan;importcom。jincou。importselector。config。MapperBean;MapperBeanpublicclassUser{}
  3)、再定一个扫描包路径的注解MyMapperScan就相当于mybatis的MapperScan注解。Retention(RetentionPolicy。RUNTIME)Target(ElementType。TYPE)DocumentedImport(MyMapperScanImportBean。class)publicinterfaceMyMapperScan{扫描包路径String〔〕basePackages()default{};}
  4)、MyMapperScanImportBean实现ImportBeanDefinitionRegistrar接口publicclassMyMapperScanImportBeanimplementsImportBeanDefinitionRegistrar,ResourceLoaderAware{privatefinalstaticStringPACKAGENAMEKEYbasePackages;privateResourceLoaderresourceLoader;搜索指定包下所有添加了MapperBean注解的类,并且把这些类添加到ioc容器里面去paramimportingClassMetadata当前类的注解信息paramregistry注册类,其registerBeanDefinition()可以注册beanOverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){1。从BeanIocScan注解获取到我们要搜索的包路径AnnotationAttributesannoAttrsAnnotationAttributes。fromMap(importingClassMetadata。getAnnotationAttributes(MyMapperScan。class。getName()));if(annoAttrsnullannoAttrs。isEmpty()){return;}String〔〕basePackages(String〔〕)annoAttrs。get(PACKAGENAMEKEY);2。找到指定包路径下所有添加了MapperBean注解的类,并且把这些类添加到IOC容器里面去ClassPathBeanDefinitionScannerscannernewClassPathBeanDefinitionScanner(registry,false);scanner。setResourceLoader(resourceLoader);路径包含MapperBean的注解的beanscanner。addIncludeFilter(newAnnotationTypeFilter(MapperBean。class));扫描包下路径scanner。scan(basePackages);}OverridepublicvoidsetResourceLoader(ResourceLoaderresourceLoader){this。resourceLoaderresourceLoader;}}
  5)测试
  这里扫描的路径就是上面User实体的位置RunWith(SpringRunner。class)SpringBootTestMyMapperScan(basePackages{com。jincou。importselector。mapperScan})publicclassUserServiceTest{AutowiredprivateUseruser;Testpublicvoidtest(){System。out。println(usernameuser。getClass()。getName());}}
  运行结果usernamecom。jincou。importselector。mapperScan。User
  完美,成功!
  实现它的基本思想是:当自己需要操作BeanFactory里面的Bean的时候,那就必须只有它才能做到了。而且它还有个方便的地方,那就是做包扫描的时候,比如MapperScan类似这种的时候,用它处理更为方便(因为扫描到了直接注册即可)

老年之后,如果发现子女开始讨厌自己,一定要做好这两件事前言在我们的生活当中有很多事,我们都需要认真考虑,不要总是觉得生活很简单,有些事情就是这样子的,如果你不能够提前考虑做好相应的准备,你的生活可能就会过得比较复杂,慢慢地就会出现各式木卫二为什么可能存在生命,它是否具有宜居性?如果木卫二存在一个像地球一样含氧的海洋,那么氧化剂需要从木卫二的表面冰层向下传播。实现这一目标的一种可能是通过木卫二上发生的地质过程中向下的地表物质运输。科学家们计算出,如果从冰层2023年发布!哪吒全新两门纯电轿跑谍照曝光近日从网络上获取一组哪吒全新两门轿跑哪吒E的路试谍照。新车基于哪吒山海平台打造的中型纯电轿跑,将于2023年内发布。动力上,搭载单双电机四驱系统,CLTC综合续航最大可达580km四川企业退休男职工能领多少养老金?坐标四川,某企业职工,男,1962年出生,1985。8参加工作,2022。11退休,退休年龄60周岁,累计缴费月数439个月,个人账户储存额10w。养老金核算1。基础养老金(月计发助力中小微企业稳增长调结构强能力若干措施出台央视网消息(新闻联播)近日,国务院促进中小企业发展工作领导小组办公室印发助力中小微企业稳增长调结构强能力若干措施。针对中小微企业当前面临的生产经营困难,国家将从政策支持融资促进扩大2022年科技企业盘点寒气袭来,不确定性背后是希望大浪淘沙后,真正的价值开始浮现。在寒气袭来的时间里,总有一些企业能够保持领先,在变化中看到希望。回首2022年,复杂变化的地缘政治多地散发的国内疫情整体通胀上升的金融市场,种种因素亚历山大34分雷霆终结掘金9连胜!约基奇缺阵NBA常规赛1月23日继续进行,本场比赛约基奇缺阵。最终,雷霆以10199战胜掘金,掘金的9连胜被终结!首节开始,掘金上来手感不佳,雷霆趁势打出188开局。穆雷上篮戈登三分缩小分差什么色号的口红喜庆,看看春晚女明星的解题思路艾瑞巴蒂,过年好呀!如果说一年中最喜庆的盛事,当然要数春晚啦。一年又一年,春晚对于很多人来说,就是全家人坐在一起磕着瓜子,对于节目抒发一些个人观点的时刻。但是,到了自媒体时代,春晚穿得越多越暖和?冬天穿衣误区,你中了几条?冬天穿衣,总担心穿得不够。羽绒服下,秋衣衬衣背心卫衣全都套上,臃肿得像个熊宝宝。难受不说,走在外面还觉得不暖和。实际上羽绒服里穿得多,真不见会更暖和。图片来源视觉中国给大家介绍一个张天爱晒拜年照扎双麻花辫穿吊带休闲超短裤秀长腿又纯又欲娱兔迎春张天爱晒出新年美照来给大家拜年了,只见张天爱扎着双麻花辫,穿着一身白色吊带休闲套装,秀出了她的一双美腿。好清凉的拜年照哈哈。扎双马尾超清新灵动。就连脚脚也是好看的呢。双手捂为了活着你为什么拼命挣钱1为了让自己过得好一点说到让自己过得好一点,相信很多人的想法都是各不相同的,有人觉得一个人想要让自己的过得更好并没有什么不对,毕竟生活在这个世界上的任何一个人都有这
产后42天检查需要空腹吗?你好,我是安柏妈妈。很高兴回答你的问题。r产后42天检查不需要空腹。r产后42天检查的内容如下r1)对新妈妈整体身体状况的评估一般包括测体重量血压检查血糖尿常规血常规等常规项目的检现在得颈椎病肩周炎腰间盘突出椎间盘突出坐骨神经痛骨刺的人怎么那么多?(o),一下一堆问题,归根结底有的问题多,有两个方面,一个是现在的生活模式,这些疾病容易高发,还有一个很重要的原因就是医院处理病痛的方案综合效果不是特别的理想,总看不好才显得多!纠现在很多的年轻人喜欢中性的打扮,分不出男女,你能接受吗?感谢邀请!对于中性装扮,从形象管理的角度上来看,中性风本来就是时尚的一种风格。女性男装化,比女性的女人味十足,视觉效果明显的时尚了很多。同样男性引用女性的服装元素,也会显得时尚度提2022年3月以后,微信支付宝还能付钱吗?从2022年3月1号开始,个人收款码禁用于经营性服务,禁止个人静态收款码被用于远程非面对面收款,你可能以为它只是一张码的事,但是它背后的大棋局,一定是你想象不到的。首先各位审题能不陈亚男为什么退还全部彩礼,难道真的守身如玉?我们换个思路考虑,假如是你,你会做赔本的买卖?好,白给人家当一年老婆,然后彩礼退了,这不是傻吗,所以,我觉得,她肯定考虑过,权衡利弊,觉得这样做,她不亏,才会这么做,至于为什么不亏去除眼袋有哪些好办法呢?1。眼下按摩睁大眼睛食指中指无名指并拢,放在眼下眼袋的位置,按揉分钟上眯着眼睛重复上面的手法按摩一分钟2。眼头按摩用中指指腹按揉眼头凹陷处到眉头,按揉一分钟3。鱼腰穴,位于眉毛中间放支架的冠状动脉多久复查一次,为什么?支架植入是治疗冠心病的一个重要的方法,而且是非常重要的方法,我经常和我的同事以及患者说,如果没有介入治疗,那么心内科的医生就失去了一个非常有用的一只手臂。因为截止到目前冠心病较为有不锻炼吧,又怕身体不好。锻炼吧,膝盖疼。该怎样好呢?你好!这也是很多人纠结的问题,特别是中老年人,建议适度锻炼,不要做大动作高强度的锻炼,比如打篮球踢足球爬山等。做些舒缓的有氧运动就可以了,比如散步慢跑太极拳八段锦广播体操等。现在人炒股用的一机多屏电脑是如何搭建的,需要什么配置?请懂行的指教?我是一名职业交易员,我们公司的电脑全部入是6屏,我是亲自参与了组装的,我发了个视频包括配置和设备买什么都说的很清楚,希望可以帮到您。简单来说,搭建多屏显示,需要多个显示器和一张支持2021下半年想买车,落地11万左右,选择什么车比较好?轿车推荐日产轩逸(合资),本田飞度(合资),吉利缤瑞,帝豪(国产),大众polo(合资),起亚k2(合资),福特福睿斯(合资)SUV五菱凯旋(国产),哈弗m6(国产),宝骏510(大拌菜酸甜汁怎么熬?大拌菜酸甜汁怎么熬?大拌菜是非常好吃的一道凉菜,但是它的做法有很多种,要说最好吃的,那要属酸甜口的大拌菜了。酸酸甜甜的料汁让这道菜特别开胃好吃,虽然它是一道凉菜,但是味道却非常棒,
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网