Denna artikel är en spegelartikel om maskinöversättning, klicka här för att hoppa till originalartikeln.

Utsikt: 15336|Svar: 0

[Källa] Undantaget löses genom att injicera RedisTemplate-instansen i SpringBoot

[Kopiera länk]
Publicerad på 2019-03-11 13:25:56 | | | |
Nyligen användes RedisTemplate under projektutveckling, och enhetstestning ledde till "Field redisTemplate in com.example.demo1.dao.RedisDao krävde en bean av typen 'org.springframework.data.redis.core.RedisTemplate' som kunde inte hittas", vilket översätts till "kunde inte hitta en böna av typen RedisTemplate". Naturligtvis, enbart genom att titta på denna mening, kan vi inte vara säkra på varför detta problem uppstår. Lägg nu upp en detaljerad fellogg.

2018-08-10 14:53:49.761 - Fångade undantag när TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] kunde förbereda 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.prepareTestInstance(ServletTestExecutionListener.java:131)
    på org.springframework.test.context.TestContextManager.prepareTestTestInstance(TestContextManager.java:230)
    på 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)
    på 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)
Orsakat av: org.springframework.beans.factory.UnsatisfiedDependencyException: Fel som skapar böna med namnet 'redisDao': Unsatisfied dependency uttryckt genom fält ' redisTemplate'; Nested exception är org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean av typen 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' tillgänglig: förväntas ha minst 1 böna som kvalificerar som autowire-kandidat. Beroendeannotationer: {@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)
    på 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)
    på 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 vanliga ramar utelämnade
Orsakad av: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean av typen 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' tillgänglig: förväntas ha minst 1 böna som kvalificerar som autowire-kandidat. Beroendeannotationer: {@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)
    på org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    på org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 vanliga ramar utelämnade
Att se denna stora fellogg är lite svindlande, faktiskt behöver vi bara titta på nyckelfelloggarna för att hitta problemet. Den andra orsakad av i felloggen skriver ut nyckelfelsloggen:No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

Författaren tittar tillbaka på den skrivna koden och specificerar den specifika typen när RedisTemplate injiceras< K, V>.


Enligt felloggen, kontrollera koden på rad 1493 i klassen DefaultListableBeanFactory, källkoden är följande:

Dessa två metoder visar att ingen böna kan matchas < RedisTemplate String, Object, >, så hur löser man detta problem? Du kan vilja använda RedisTemplate< K, V> utan att specificera den specifika typen, och ändra koden enligt följande:

Starta om tjänsten, inget fel rapporteras i uppstartsloggen, och RedisTemplate injicerar bönan framgångsrikt. Jag undrar varför RedisTemplate< String, Object> injicering beans misslyckas. Efter att ha funderat länge på det trodde jag att RedisTemplate automatiskt konfigureras i SpringBoot-ramverket, och att standarden i containern är instansen av RedisTemplate. Med detta i åtanke behöver du bläddra igenom de officiella webbplatsdokumenten för att se om det finns någon förklaring där. Mycket riktigt förklarar avsnitt 30.1.1 i den officiella dokumentationen fortfarande RedisTemplate.

Officiell dokumentadress:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Om du lägger till din egen@Beanav alla autokonfigurerade typer ersätter den standarden (förutom i fallet RedisTemplate, när undantaget baseras på bönans namn redisTemplate, inte dess typ).
Om du lägger till din egen böna för autokonfigurationstypen kommer den att ersätta standardvarianten. Min kod verkar vara okej, vänta... Denna mening inom parentes är poängen. Översätt en våg,Förutom i fallet RedisTemplate, när man utesluter baserat på bönans namn, inte dess typ. Engelskan är inte särskilt bra, och det verkar som att översättningen inte är särskilt smidig.

Nu verkar det vara förstått att RedisTemplate< String, Object > använts @Autowired vid injicering,@Autowired monterade efter typ som standard。 Med andra ord, om du vill få bönorna > RedisTemplate< String, Object, måste du montera dem enligt deras namn. Då bör du naturligtvis tänka på att använda den@Resource monteras den som standard enligt namnet。 Ändra koden igen enligt följande:


Anteckningen har ändrats från @Autowired till @Resource Projektet startade utan fel, och det löstes perfekt!

Starta om tjänsten igen, startloggen rapporterar inget fel, och RedisTemplate< String, Object> injicerar bönan framgångsrikt. Genom detta fel lärde jag mig en funktion i autokonfigurationsklassen i SpringBoot-ramverket. Samtidigt speglar det också att inlärning av en teknik bör börja från den officiella webbplatsen för att undvika att trampa på gropen.
I själva utvecklingsprocessen, med RedisTemplate< kräver K, V> inte att man specificerar typen av K och V, och standardbönan kan uppfylla kraven.

Slutligen vill jag verifiera ett litet problem och modifiera koden igen enligt följande:


Ovanstående kod specificerar att K och V båda är strängtyper när man injicerar RedisTemplate, och jämför om redisTemplate och stringRedisTemplate är samma objekt i compare()-metoden. Kör enhetstestklassen, och testresultaten är följande:

2018-08-10 18:30:57.075 - Startade Demo1ApplicationTests på 15,58 sekunder (JVM körde på 16,974)
2018-08-10 18:30:57.360 - hashcode:1996087296 för redisTemplate
2018-08-10 18:30:57.360 - stringRedisTemplate hashkod:1996087296
2018-08-10 18:30:57.363 - Resultat lika(): sant
2018-08-10 18:30:57.364 - Jämförelseresultat av redisTemplate och stringRedisTemplate: true
Testresultaten visar att redisTemplate och stringRedisTemplate är samma objekt. Vänta en minut... Varför är det inte fel att specificera att K och V är strängar när man injicerar RedisTemplate den här gången? Dessutom visade sig de två föremålen vara samma föremål. Låt oss titta på källkoden till StringRedisTemplate.

Efter att ha läst källkoden, förstår du, för föräldraklassen till StringRedisTemplate-klassen är RedisTemplate< String, String>, och bönan är som standard singleton, och de två är naturligt samma objekt.




Föregående:Cast till värdetyp "System.Decimal" misslyckades...
Nästa:Felet skapar böna med namnet 'stringRedisTemplate' definierat i...
Friskrivning:
All programvara, programmeringsmaterial eller artiklar som publiceras av Code Farmer Network är endast för lärande- och forskningsändamål; Ovanstående innehåll får inte användas för kommersiella eller olagliga ändamål, annars kommer användarna att bära alla konsekvenser. Informationen på denna sida kommer från internet, och upphovsrättstvister har inget med denna sida att göra. Du måste helt radera ovanstående innehåll från din dator inom 24 timmar efter nedladdning. Om du gillar programmet, vänligen stöd äkta programvara, köp registrering och få bättre äkta tjänster. Om det finns något intrång, vänligen kontakta oss via e-post.

Mail To:help@itsvse.com