Tento článok je zrkadlovým článkom o strojovom preklade, kliknite sem pre prechod na pôvodný článok.

Pohľad: 15336|Odpoveď: 0

[Zdroj] Výnimka sa vyrieši injekciou inštancie RedisTemplate v SpringBoot

[Kopírovať odkaz]
Zverejnené 11. 3. 2019 13:25:56 | | | |
Nedávno sa počas vývoja projektu použil RedisTemplate a unit testing vyvolal "Field redisTemplate in com.example.demo1.dao.RedisDao vyžadoval fazuľu typu 'org.springframework.data.redis.core.RedisTemplate', ktorá nebolo možné nájsť", čo znamená "nepodarilo sa nájsť fazuľu typu RedisTemplate". Samozrejme, keď sa pozrieme len na túto vetu, nemôžeme si byť istí, prečo tento problém vzniká. Teraz zverejnite podrobný záznam chýb.

2018-08-10 14:53:49.761 - Zachytil výnimku pri umožnení TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] pripraviť test Príklad [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    na stránkach org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    na org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    na org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    na org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    na org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    na org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    na org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    na org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    na org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    na org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Spôsobené: org.springframework.beans.factory.UnsatisfiedDependencyException: Chyba vytvárajúca fazuľu s názvom 'redisDao': Nesplnená závislosť vyjadrená cez pole ' redisTemplate'; vnorená výnimka je org.springframework.beans.factory.NoSuchBeanDefinitionException: Žiadny kvalifikujúci bean typu 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' Dostupné: očakáva sa aspoň 1 fazuľa, ktorá spĺňa kritériá Autowire. Anotácie závislostí: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    na org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    na org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    na org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    na org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    na org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    na org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    na org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    na org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    na org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    na org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 25 bežných rámcov vynechaných
Spôsobené: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' Dostupné: očakáva sa aspoň 1 fazuľa, ktorá spĺňa kritériá Autowire. Anotácie závislostí: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 bežných rámcov vynechaných
Vidieť tento veľký záznam chýb je trochu mätúce, v skutočnosti stačí pozrieť kľúčové záznamy chýb, aby sme našli problém. Druhý Caused by v error logu vypíše kľúčový error log:No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

Autor sa spätne pozrie na napísaný kód a špecifikuje konkrétny typ pri vkladaní RedisTemplate< K, V>.


Podľa záznamu chýb, skontrolujte kód na riadku 1493 triedy DefaultListableBeanFactory, zdrojový kód je nasledovný:

Tieto dve metódy ukazujú, že žiadna fazuľa nemožno priradiť < RedisTemplate String, Object >, takže ako tento problém vyriešiť? Môžete použiť RedisTemplate< K, V> bez špecifikovania konkrétneho typu a upraviť kód nasledovne:

Reštartujem službu, v spustovacom logu sa nehlási žiadna chyba a RedisTemplate úspešne vstrekne zrno. Zaujímalo by ma, prečo RedisTemplate< String, Object> injektovanie fazúľ zlyháva. Po dlhom premýšľaní som si myslel, že RedisTemplate je automaticky konfigurovaný v SpringBoot frameworku a predvolená inštancia v kontajneri je inštancia RedisTemplate. Keď nad tým premýšľate, mali by ste si prelistovať oficiálne dokumenty na webovej stránke, aby ste zistili, či v oficiálnych dokumentoch nie je nejaké vysvetlenie. A naozaj, sekcia 30.1.1 oficiálnej dokumentácie stále vysvetľuje RedisTemplate.

Oficiálna adresa dokumentu:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Ak si pridáte svoje vlastné@Beanz akéhokoľvek automaticky konfigurovaného typu nahrádza predvolený (okrem prípadu RedisTemplate, kde je vylúčenie založené na názve zrna redisTemplate, nie na jeho type).
Ak pridáte vlastné zrno pre automatickú konfiguráciu, nahradí to predvolené. Môj kód sa zdá byť v poriadku, počkaj... Táto veta v zátvorkách je pointa. Prelož vlnu,Okrem prípadu RedisTemplate, keď sa vylučuje podľa názvu zrna, nie podľa jeho typu. Angličtina nie je veľmi dobrá a zdá sa, že preklad nie je veľmi plynulý.

Teraz sa zdá, že RedisTemplate< String, Object > použitý @Autowired pri injekcii,@Autowired zostavené podľa typu predvolene。 Inými slovami, ak chcete získať zrná > RedisTemplate< String, Object, musíte ich zostaviť podľa ich názvov. Potom prirodzene uvažuj o jeho použití@Resource sa zostavuje predvolene podľa názvu。 Kód upravte znova nasledovne:


Anotácia bola zmenená z @Autowired na @Resource Projekt začal bez chyby a bol dokonale vyriešený!

Reštartujte službu znova, štartovací log nehlási chybu a RedisTemplate< String, Object> úspešne vstrekne bean. Vďaka tejto chybe som sa naučil funkciu triedy automatickej konfigurácie v rámci SpringBootu. Zároveň to tiež odráža, že učenie technológie by sa malo začať na oficiálnej webovej stránke, aby sa predišlo stúpeniu na jamu.
V skutočnom vývojovom procese, pri použití RedisTemplate< K, V> nevyžaduje špecifikovanie typu K a V a predvolené zrno môže splniť požiadavky.

Nakoniec chcem overiť malý problém a kód opäť upraviť nasledovne:


Vyššie uvedený kód špecifikuje, že K a V sú oba typy reťazcov pri injekcii RedisTemplate, a porovnáva, či sú redisTemplate a stringRedisTemplate ten istý objekt v metóde compare(). Spustite triedu jednotkového testu a výsledky testu sú nasledovné:

2018-08-10 18:30:57.075 - Spustili Demo1ApplicationTests za 15,58 sekundy (JVM bežal 16,974)
2018-08-10 18:30:57.360 - hashcode:1996087296 pre redisTemplate
2018-08-10 18:30:57.360 - stringRedisTemplate hashcode:1996087296
2018-08-10 18:30:57.363 - Výsledok equal(): true
2018-08-10 18:30:57.364 - Výsledok porovnania redisTemplate a stringRedisTemplate: true
Výsledky testu ukazujú, že redisTemplate a stringRedisTemplate sú ten istý objekt. Počkaj chvíľu... Prečo nie je nesprávne špecifikovať, že K a V sú reťazce pri injektovaní RedisTemplate tentoraz? Navyše, ukázalo sa, že oba objekty sú ten istý objekt. Pozrime sa na zdrojový kód StringRedisTemplate.

Po prečítaní zdrojového kódu, rozumiete, pretože nadradená trieda triedy StringRedisTemplate je RedisTemplate< String, String> a bean je predvolene singleton, takže oba sú prirodzene ten istý objekt.




Predchádzajúci:Cast to value typ "System.Decimal" zlyhal...
Budúci:Chyba pri vytváraní fazule s názvom 'stringRedisTemplate' definovaným v...
Vyhlásenie:
Všetok softvér, programovacie materiály alebo články publikované spoločnosťou Code Farmer Network slúžia len na vzdelávacie a výskumné účely; Vyššie uvedený obsah nesmie byť použitý na komerčné alebo nezákonné účely, inak nesú všetky následky používateľmi. Informácie na tejto stránke pochádzajú z internetu a spory o autorské práva s touto stránkou nesúvisia. Musíte úplne vymazať vyššie uvedený obsah zo svojho počítača do 24 hodín od stiahnutia. Ak sa vám program páči, podporte originálny softvér, zakúpte si registráciu a získajte lepšie originálne služby. Ak dôjde k akémukoľvek porušeniu, kontaktujte nás prosím e-mailom.

Mail To:help@itsvse.com