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

Autowired的这些骚操作,你都知道吗

  最近review别人代码的时候,看到了一些Autowired不一样的用法,觉得有些意思,特定花时间研究了一下,收获了不少东西,现在分享给大家。
  也许Autowired比你想象中更强大。
  1。Autowired的默认装配
  我们都知道在spring中Autowired注解,是用来自动装配对象的。通常,我们在项目中是这样用的:packagecom。sue。cache。service;importorg。springframework。stereotype。Service;ServicepublicclassTestService1{publicvoidtest1(){}}packagecom。sue。cache。service;importorg。springframework。stereotype。Service;ServicepublicclassTestService2{AutowiredprivateTestService1testService1;publicvoidtest2(){}}
  没错,这样是能够装配成功的,因为默认情况下spring是按照类型装配的,也就是我们所说的byType方式。
  此外,Autowired注解的required参数默认是true,表示开启自动装配,有些时候我们不想使用自动装配功能,可以将该参数设置成false。2。相同类型的对象不只一个时
  上面byType方式主要针对相同类型的对象只有一个的情况,此时对象类型是唯一的,可以找到正确的对象。
  但如果相同类型的对象不只一个时,会发生什么?
  在项目的test目录下,建了一个同名的类TestService1:packagecom。sue。cache。service。test;importorg。springframework。stereotype。Service;ServicepublicclassTestService1{publicvoidtest1(){}}
  重新启动项目时:Causedby:org。springframework。context。annotation。ConflictingBeanDefinitionException:AnnotationspecifiedbeannametestService1forbeanclass〔com。sue。cache。service。test。TestService1〕conflictswithexisting,noncompatiblebeandefinitionofsamenameandclass〔com。sue。cache。service。TestService1〕
  结果报错了,报类类名称有冲突,直接导致项目启动不来。
  注意,这种情况不是相同类型的对象在Autowired时有两个导致的,非常容易产生混淆。这种情况是因为spring的Service方法不允许出现相同的类名,因为spring会将类名的第一个字母转换成小写,作为bean的名称,比如:testService1,而默认情况下bean名称必须是唯一的。
  下面看看如何产生两个相同的类型bean:publicclassTestService1{publicvoidtest1(){}}ServicepublicclassTestService2{AutowiredprivateTestService1testService1;publicvoidtest2(){}}ConfigurationpublicclassTestConfig{Bean(test1)publicTestService1test1(){returnnewTestService1();}Bean(test2)publicTestService1test2(){returnnewTestService1();}}
  在TestConfig类中手动创建TestService1实例,并且去掉TestService1类上原有的Service注解。
  重新启动项目:
  果然报错了,提示testService1是单例的,却找到两个对象。
  其实还有一个情况会产生两个相同的类型bean:publicinterfaceIUser{voidsay();}ServicepublicclassUser1implementsIUser{Overridepublicvoidsay(){}}ServicepublicclassUser2implementsIUser{Overridepublicvoidsay(){}}ServicepublicclassUserService{AutowiredprivateIUseruser;}
  项目重新启动时:
  报错了,提示跟上面一样,testService1是单例的,却找到两个对象。
  第二种情况在实际的项目中出现得更多一些,后面的例子,我们主要针对第二种情况。3。Qualifier和Primary
  显然在spring中,按照Autowired默认的装配方式:byType,是无法解决上面的问题的,这时可以改用按名称装配:byName。
  只需在代码上加上Qualifier注解即可:ServicepublicclassUserService{AutowiredQualifier(user1)privateIUseruser;}
  只需这样调整之后,项目就能正常启动了。
  Qualifier意思是合格者,一般跟Autowired配合使用,需要指定一个bean的名称,通过bean名称就能找到需要装配的bean。
  除了上面的Qualifier注解之外,还能使用Primary注解解决上面的问题。在User1上面加上Primary注解:PrimaryServicepublicclassUser1implementsIUser{Overridepublicvoidsay(){}}
  去掉UserService上的Qualifier注解:ServicepublicclassUserService{AutowiredprivateIUseruser;}
  重新启动项目,一样能正常运行。
  当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有Primary注解修饰,该候选者会被选中,作为自动配置的值。4。Autowired的使用范围
  上面的实例中Autowired注解,都是使用在成员变量上,但Autowired的强大之处,远非如此。
  先看看Autowired注解的定义:
  从图中可以看出该注解能够使用在5种目标类型上,下面用一张图总结一下:
  该注解我们平常使用最多的地方可能是在成员变量上。
  接下来,我们重点看看在其他地方该怎么用?4。1成员变量
  在成员变量上使用Autowired注解:ServicepublicclassUserService{AutowiredprivateIUseruser;}
  这种方式可能是平时用得最多的。4。2构造器
  在构造器上使用Autowired注解:ServicepublicclassUserService{privateIUseruser;AutowiredpublicUserService(IUseruser){this。useruser;System。out。println(user:user);}}
  注意,在构造器上加Autowired注解,实际上还是使用了Autowired装配方式,并非构造器装配。4。3方法
  在普通方法上加Autowired注解:ServicepublicclassUserService{Autowiredpublicvoidtest(IUseruser){user。say();}}
  spring会在项目启动的过程中,自动调用一次加了Autowired注解的方法,我们可以在该方法做一些初始化的工作。
  也可以在setter方法上Autowired注解:ServicepublicclassUserService{privateIUseruser;AutowiredpublicvoidsetUser(IUseruser){this。useruser;}}4。4参数
  可以在构造器的入参上加Autowired注解:ServicepublicclassUserService{privateIUseruser;publicUserService(AutowiredIUseruser){this。useruser;System。out。println(user:user);}}
  也可以在非静态方法的入参上加Autowired注解:ServicepublicclassUserService{publicvoidtest(AutowiredIUseruser){user。say();}}4。5注解
  这种方式其实用得不多,我就不过多介绍了。5。Autowired的高端玩法
  其实上面举的例子都是通过Autowired自动装配单个实例,但这里我会告诉你,它也能自动装配多个实例,怎么回事呢?
  将UserService方法调整一下,用一个List集合接收IUser类型的参数:ServicepublicclassUserService{AutowiredprivateListIUseruserList;AutowiredprivateSetIUseruserSet;AutowiredprivateMapString,IUseruserMap;publicvoidtest(){System。out。println(userList:userList);System。out。println(userSet:userSet);System。out。println(userMap:userMap);}}
  增加一个controller:RequestMapping(u)RestControllerpublicclassUController{AutowiredprivateUserServiceuserService;RequestMapping(test)publicStringtest(){userService。test();returnsuccess;}}
  调用该接口后:
  从上图中看出:userList、userSet和userMap都打印出了两个元素,说明Autowired会自动把相同类型的IUser对象收集到集合中。
  意不意外,惊不惊喜?6。Autowired一定能装配成功?
  前面介绍了Autowired注解这么多牛逼之处,其实有些情况下,即使使用了Autowired装配的对象还是null,到底是什么原因呢?6。1没有加Service注解
  在类上面忘了加Controller、Service、Component、Repository等注解,spring就无法完成自动装配的功能,例如:publicclassUserService{AutowiredprivateIUseruser;publicvoidtest(){user。say();}}
  这种情况应该是最常见的错误了,不会因为你长得帅,就不会犯这种低级的错误。6。2注入Filter或Listener
  web应用启动的顺序是:listenerfilterservlet。
  接下来看看这个案例:publicclassUserFilterimplementsFilter{AutowiredprivateIUseruser;Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{user。say();}OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{}Overridepublicvoiddestroy(){}}ConfigurationpublicclassFilterConfig{BeanpublicFilterRegistrationBeanfilterRegistrationBean(){FilterRegistrationBeanbeannewFilterRegistrationBean();bean。setFilter(newUserFilter());bean。addUrlPatterns();returnbean;}}
  程序启动会报错:
  tomcat无法正常启动。
  什么原因呢?
  众所周知,springmvc的启动是在DisptachServlet里面做的,而它是在listener和filter之后执行。如果我们想在listener和filter里面Autowired某个bean,肯定是不行的,因为filter初始化的时候,此时bean还没有初始化,无法自动装配。
  如果工作当中真的需要这样做,我们该如何解决这个问题呢?publicclassUserFilterimplementsFilter{privateIUseruser;Overridepublicvoidinit(FilterConfigfilterConfig)throwsServletException{ApplicationContextapplicationContextWebApplicationContextUtils。getWebApplicationContext(filterConfig。getServletContext());this。user((IUser)(applicationContext。getBean(user1)));user。say();}OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{}Overridepublicvoiddestroy(){}}
  答案是使用WebApplicationContextUtils。getWebApplicationContext获取当前的ApplicationContext,再通过它获取到bean实例。6。3注解未被ComponentScan扫描
  通常情况下,Controller、Service、Component、Repository、Configuration等注解,是需要通过ComponentScan注解扫描,收集元数据的。
  但是,如果没有加ComponentScan注解,或者ComponentScan注解扫描的路径不对,或者路径范围太小,会导致有些注解无法收集,到后面无法使用Autowired完成自动装配的功能。
  有个好消息是,在springboot项目中,如果使用了SpringBootApplication注解,它里面内置了ComponentScan注解的功能。6。4循环依赖问题
  如果A依赖于B,B依赖于C,C又依赖于A,这样就形成了一个死循环。
  spring的bean默认是单例的,如果单例bean使用Autowired自动装配,大多数情况,能解决循环依赖问题。
  但是如果bean是多例的,会出现循环依赖问题,导致bean自动装配不了。
  还有有些情况下,如果创建了代理对象,即使bean是单例的,依然会出现循环依赖问题。
  如果你对循环依赖问题比较感兴趣,也可以看一下我的另一篇专题《》,里面介绍的非常详细。7。Autowired和Resouce的区别
  Autowired功能虽说非常强大,但是也有些不足之处。比如:比如它跟spring强耦合了,如果换成了JFinal等其他框架,功能就会失效。而Resource是JSR250提供的,它是Java标准,绝大部分框架都支持。
  除此之外,有些场景使用Autowired无法满足的要求,改成Resource却能解决问题。接下来,我们重点看看Autowired和Resource的区别。Autowired默认按byType自动装配,而Resource默认byName自动装配。Autowired只包含一个参数:required,表示是否开启自动准入,默认是true。而Resource包含七个参数,其中最重要的两个参数是:name和type。Autowired如果要使用byName,需要使用Qualifier一起配合。而Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配。Autowired能够用在:构造器、方法、参数、成员变量和注解上,而Resource能用在:类、成员变量和方法上。Autowired是spring定义的注解,而Resource是JSR250定义的注解。
  此外,它们的装配顺序不同。
  Autowired的装配顺序如下:
  Resource的装配顺序如下:如果同时指定了name和type:如果指定了name:如果指定了type:如果既没有指定name,也没有指定type:
  后记
  我原本打算接下来写Autowired原理分析和源码解读的,但是由于篇幅太长了,不适合放在一起,后面打算开个专题。如果有兴趣的朋友,可以持续关注我后续的文章,相信你读完必定会有些收获。
  原文链接:https:mp。weixin。qq。comscoKa4xPrr5k8djlkZyQKWg

休闲的好选择,热门的手游盘点活下去丧尸的哀嚎响彻街道,破碎的院落遍藏杀机。想要在这个末世里活下去,你需要水!食物!武器!还有安全屋!去搜寻每一座你看到建筑,把能找到的一切资源搬回你的家,噢!别忘了,你需要一个这些手游精品,周末还不来玩军团战棋英雄时代军团战棋英雄时代是一款由2人制作的魔幻风格的中型4X策略游戏。玩家将会扮演军团首领,在游戏中建设自己的城堡和领地,探索未知的大陆,搜寻各种宝物,培养自己的英雄和军队放松自我,这些手游真不错脑洞旅行旅行题材的脑洞解谜游戏,包含解谜寻物找茬等玩法,玩家利用自己的脑洞去环游世界,感受每个国家的特色剧情和解谜玩法,组装自己喜欢的旅行车辆。智斗小偷邂逅小姐姐逃离食人族偶遇魔法掌上的快乐,不该错过的手机好游戏文字仙侠文字仙侠mud游戏是一款题材设计独特玩法有着极大创意的江湖类文字游戏,创新的剧情设计以及各种挑战玩法的加入给每个玩家一场场畅快淋漓的武林人生,你将在这个文字世界里开启你的热手游也太好玩了,快乐原来这么简单极品飞车无极限赛车在面向移动平台的首款预售版极品飞车游戏中称霸赛道真实赛车3开发团队为您倾情打造。用种类繁多的赛车和定制选项来打造您的梦幻座驾。在混乱与掌控之间释放自我,在油门轰鸣春节将至,这些手游别错过奇缘之旅奇缘之旅摒弃传统卡牌所用的敌我双战场的布局形式,转而使用全新的三战场形式,新增的战场为战斗带来了无限可能。各位旅团长在冒险中将会遭遇多种阵型战斗的考验,除了传统的正面冲锋对精品手游盘点,让你不再无聊的优秀游戏妙奇星球妙奇星球是一款星球探险收集游戏。在这个有点古怪的宇宙里,可爱的角色们将陪你一同游历漫长星河,经历一段段充满意外和惊喜的冒险,精灵魔塔精灵魔塔是一款原创的全新玩法游戏,结合了随时随地享受快乐,这个周末不再无聊雨城雨城是一款水彩绘本风格的第三人称解谜游戏。游戏里玩家会扮演一只猫咪,来到一座常年下雨的城市雨城,找寻失踪的狐狸妹妹的旅程。其间会遇到形形色色的动物人物,经历光怪陆离的故事。传奇掌上游戏推荐,随时随地享受快乐道友合成器一款可合成修士布局宗门建筑获得随机装备与神通离线生产探索城市与险境的修仙游戏。全民数独独具魅力的数字解密游戏,一分钟入门!精彩数独世界欢迎你的到来直观的教学模式,上手只要好玩游戏别错过,精品手游让你随时随地享受快乐加德尔契约加德尔契约是一款让人耳目一新的西方魔幻题材的卡牌养成对战手游,故事以人类魔法师与神灵观察者的思想与理念的对抗为背景,创造一个魔法与科技发展融合的世界。玩家在游戏里面扮演拥这些游戏值得一玩,好玩的手游推荐迷你地下城传奇曾经被封印的魔王已经苏醒世界再次陷入黑暗。你决定进入阴森的地牢去击败邪恶的敌人,只有这样才能拯救我的王国。滑动屏幕移动你的角色,在地牢中寻找你的朋友并共同击败敌人赢的
怪物猎人物语2毁灭之翼剧情预告片公布怪物猎人系列衍生的RPG游戏新作怪物猎人物语2毁灭之翼即将于7月9日发售,官方公布了本作最新剧情预告视频。视频地址怪物猎人物语2毁灭之翼讲述了怪物猎人世界观下,以骑士这一与怪物共生传奇世界好不容易肝出的元神,合击竟如此强力传奇世界1。90版本的元神,是小编目前为止觉得可玩性最大的一个版本。它不仅有着角色直接的技能衔接搭配,还有元神与角色之间的合击,既然是元神版,那么合击就一定是要非常慎重考虑的选择。王者荣耀金币夺宝终于上线了,兑换奖励有些水,老玩家很失望王者早知道,小于来爆料,大家好我是小于王者荣耀体验服在5月20号10001600进行停机更新,本次更新的内容超级多,基本上就是在为S24赛季的更新做先行准备!小于将分成两篇文章给大大航海时代4威力加强版HD简评重温七海霸主梦大航海时代系列是很多玩家的地理启蒙,今天5月20日光荣复刻的大航海时代4威力加强版HD正式解锁,邀请大家重温旧梦。大航海时代4威力加强版HD游戏类型经营模拟发售日期2021。5。2碰到野猪不要杀,黑暗与光明手游高手驯服它后食物吃不完黑暗与光明手游是一款由虚幻4打造的沙盒手游,这款游戏中最值得一说的就是其中硬核的生存玩法,玩家要面对一个拥有宏伟世界观的荒凉星球,这里有着超过4万平方公里的世界地图,玩家徒步绕一圈虎牙和小象互娱开启京城大师赛,狼王JY发挥出色,网友表示佩服狼人杀游戏大家都有所了解,也是一个非常考验演技和智商的游戏,对于普通的玩家来说,还是非常有难度的,但作为观众看这样的游戏,还是非常有意思的,尤其是看到里面的玩家各种神奇的操作,总会99元就能买到的好手柄北通蝙蝠4游戏手柄评测在游戏手柄领域,100元以下的市场属于入门级别的领域,有着庞大的用户数量,不少玩家的第一个手柄都会从这个价位考虑,并体验和键鼠游戏不同的游戏操控感。因此,这个价位段的产品谁的功能全男人,应该对自己好一点初中时代,在游戏机室的PS1上遇到了生化危机1,当时给我的震撼太强大了,但上一辈人强烈反对玩游戏,所以我一直有个梦,就是掏自己的钱,买一台属于我的PS。毕业以后,因诸多原因,错过了王者扭蛋机奖励送不停,300限时点券开放领取,永久皮肤八选一王者荣耀这款游戏中的福利活动还是挺多的,相信不少玩家都参与了王者扭蛋机的活动,这个活动大家可以领取限时点券以及红包的奖励,最重要的是可以获取永久史诗皮肤,如果说获取了永久史诗皮肤宝王者荣耀KPL卡位赛,LGD大鹅Hero巅峰对决,春季冠军提前淘汰休赛相信小伙伴们都知道,王者荣耀KPL卡位赛第一天已经结束,在第一天当中就有一些对局让大家觉得精彩,赶紧来看看吧!首先就是LGD大鹅和Hero的比赛。在这场比赛开始之前大家一边倒地认为众多王者主播不务正业?不打巅峰赛玩起碰碰车,还有众多神秘选手在王者荣耀中如果想要证明自己的技术,那么巅峰赛就是最好的选择。之所以这么说归根结底还是因为两个原因,首先想要参加巅峰赛,就必须要在当前赛季打到王者,具有比较高的门槛。其次巅峰赛只能
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网