Denne artikkelen er en speilartikkel om maskinoversettelse, vennligst klikk her for å hoppe til originalartikkelen.

Utsikt: 15336|Svare: 0

[Kilde] Unntaket løses ved å injisere RedisTemplate-instansen i SpringBoot

[Kopier lenke]
Publisert på 11.03.2019 13:25:56 | | | |
Nylig ble RedisTemplate brukt under prosjektutviklingen, og enhetstesting viste "Field redisTemplate in com.example.demo1.dao. RedisDao krevde en bean av typen 'org.springframework.data.redis.core.RedisTemplate' som kunne ikke bli funnet», som betyr «kunne ikke finne en bønne av typen RedisTemplate». Selvfølgelig, ut fra denne setningen alene, kan vi ikke være sikre på hvorfor dette problemet oppstår. Nå, legg ut en detaljert feillogg.

2018-08-10 14:53:49.761 - Fanget unntak mens TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] forberedte test instans [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    på org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    på org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    på org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestTestInstance(ServletTestExecutionListener.java:131)
    at org.springframework.test.context.TestContextManager.prepareTestTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    på org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    på org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    på org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    på org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    på org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    på org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    på org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    på org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    på org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    på org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    på org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    på org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    på org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    på org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    på org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    på org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    på org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    på org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    på org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Forårsaket av: org.springframework.beans.factory.UnsatisfiedDependencyException: Feil som oppretter bønne med navnet 'redisDao': Utilfredsstilt avhengighet uttrykt gjennom felt ' redisTemplate'; Nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' tilgjengelig: forventet minst 1 bønne som kvalifiserer som autowire-kandidat. Avhengighetsannotasjoner: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    på org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    på org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    på org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    på org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    på org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    på org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    på org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    på org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    på org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    på org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    på org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    på org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    på org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    på org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    på org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    på org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    på org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 25 vanlige rammer utelatt
Forårsaket av: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean av typen 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' tilgjengelig: forventet minst 1 bønne som kvalifiserer som autowire-kandidat. Avhengighetsannotasjoner: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    på 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)
    på org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 vanlige rammer utelatt
Å se denne store feilloggen er litt svimmel, faktisk trenger vi bare å se på nøkkelfeilloggene for å finne problemet. Den andre Forårsaket av i feilloggen skriver ut nøkkelfeilloggen:No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

Forfatteren ser tilbake på koden som er skrevet og spesifiserer den spesifikke typen når han injiserer RedisTemplate< K, V>.


Ifølge feilloggen, sjekk koden på linje 1493 i klassen DefaultListableBeanFactory, kildekoden er som følger:

Disse to metodene viser at ingen bønne kan matches < RedisTemplate String, Object, >, så hvordan løser man dette problemet? Du kan ønske å bruke RedisTemplate< K, V> uten å spesifisere den spesifikke typen, og endre koden som følger:

Start tjenesten på nytt, ingen feil rapporteres i oppstartsloggen, og RedisTemplate injiserer bønnen uten problemer. Jeg lurer på hvorfor RedisTemplate< String, Object> injisering av bønner mislykkes. Etter å ha tenkt lenge på det, trodde jeg at RedisTemplate automatisk er konfigurert i SpringBoot-rammeverket, og standarden i containeren er instansen av RedisTemplate. Med dette i tankene må du gå gjennom dokumentene på den offisielle nettsiden for å se om det finnes noen forklaring i dokumentene. Joda, seksjon 30.1.1 i den offisielle dokumentasjonen forklarer fortsatt RedisTemplate.

Offisiell dokumentadresse:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Hvis du legger til din egen@Beanav alle de autokonfigurerte typene, erstatter den standarden (bortsett fra i tilfellet RedisTemplate, når eksklusjonen er basert på bønnenavnet redisTemplate, ikke typen).
Hvis du legger til din egen bønne for auto-konfigurasjonstypen, vil den erstatte standarden. Koden min ser ut til å være fin, vent... Denne setningen i parentes er poenget. Oversett en bølge,Bortsett fra i tilfellet RedisTemplate, når man ekskluderer basert på bønnens navn, ikke typen. Engelsken er ikke særlig god, og det virker som oversettelsen ikke er særlig jevn.

Nå ser det ut til å være forstått at RedisTemplate< String, Object > brukt @Autowired når man injiserer,@Autowired montert etter type som standard。 Med andre ord, hvis du vil få bønnene > RedisTemplate< String, Object, må du sette dem sammen etter navnene deres. Tenk da naturlig nok på å bruke det@Resource monteres den som standard i henhold til navnet。 Endre koden igjen som følger:


Annotasjonen er endret fra @Autowired til @Resource Prosjektet startet uten feil, og det ble løst perfekt!

Start tjenesten på nytt, oppstartsloggen rapporterer ingen feil, og RedisTemplate< String, Object> injiserer bønnen med suksess. Gjennom denne feilen lærte jeg en funksjon i auto-konfigurasjonskurset i SpringBoot-rammeverket. Samtidig reflekterer det også at det å lære en teknologi bør starte fra den offisielle nettsiden for å unngå å tråkke i gropen.
I selve utviklingsprosessen, ved bruk av RedisTemplate< krever ikke K, V> spesifisering av typen K og V, og standardbønnen kan oppfylle kravene.

Til slutt vil jeg verifisere et lite problem, og endre koden igjen som følger:


Koden ovenfor spesifiserer at K og V begge er strengtyper når man injiserer RedisTemplate, og sammenligner om redisTemplate og stringRedisTemplate er det samme objektet i compare()-metoden. Kjør enhetstestklassen, og testresultatene er som følger:

2018-08-10 18:30:57.075 - Startet Demo1ApplicationTests på 15,58 sekunder (JVM kjørte på 16,974)
2018-08-10 18:30:57.360 - hashkode:1996087296 for redisTemplate
2018-08-10 18:30:57.360 - stringRedisTemplate hashkode:1996087296
2018-08-10 18:30:57.363 - Resultat lik(): sant
2018-08-10 18:30:57.364 - Sammenligningsresultat av redisTemplate og stringRedisTemplate: true
Testresultatene viser at redisTemplate og stringRedisTemplate er det samme objektet. Vent litt... Hvorfor er det ikke feil å spesifisere at K og V er strenger når man injiserer RedisTemplate denne gangen? Dessuten viste det seg at de to objektene var det samme objektet. La oss se på kildekoden til StringRedisTemplate.

Etter å ha lest kildekoden, forstår du, for foreldreklassen til StringRedisTemplate-klassen er RedisTemplate< String, String>, og bønnen er singleton som standard, og de to er naturlig det samme objektet.




Foregående:Kast til verditypen "System.Desimal" feilet...
Neste:Feil som oppretter bønne med navnet 'stringRedisTemplate' definert i...
Ansvarsfraskrivelse:
All programvare, programmeringsmateriell eller artikler publisert av Code Farmer Network er kun for lærings- og forskningsformål; Innholdet ovenfor skal ikke brukes til kommersielle eller ulovlige formål, ellers skal brukerne bære alle konsekvenser. Informasjonen på dette nettstedet kommer fra Internett, og opphavsrettstvister har ingenting med dette nettstedet å gjøre. Du må fullstendig slette innholdet ovenfor fra datamaskinen din innen 24 timer etter nedlasting. Hvis du liker programmet, vennligst støtt ekte programvare, kjøp registrering, og få bedre ekte tjenester. Hvis det foreligger noen krenkelse, vennligst kontakt oss på e-post.

Mail To:help@itsvse.com