Dit artikel is een spiegelartikel van machinevertaling, klik hier om naar het oorspronkelijke artikel te gaan.

Bekijken: 15336|Antwoord: 0

[Bron] De uitzondering wordt opgelost door de RedisTemplate-instantie in SpringBoot te injecteren

[Link kopiëren]
Geplaatst op 11-03-2019 13:25:56 | | | |
Onlangs werd RedisTemplate gebruikt tijdens projectontwikkeling, en bij unit tests werd "Field redisTemplate in com.example.demo1.dao.RedisDao vereiste een bean van het type 'org.springframework.data.redis.core.RedisTemplate' dat kon niet gevonden worden", wat vertaald kan worden als "kon geen boon van het type RedisTemplate vinden". Natuurlijk kunnen we, alleen al vanuit deze zin, niet zeker weten waarom dit probleem zich voordoet. Plaats nu een gedetailleerd foutenlogboek.

2018-08-10 14:53:49.761 - Uitzondering gevangen terwijl TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] test kon voorbereiden Instantie [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    op org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    op org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    op 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)
    op org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    op org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    op org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    op org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    op org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    op org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    op org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    op org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    op org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    op org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    op org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    op org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    op org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    op org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    op org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    op org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    op org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    op org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    op org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Veroorzaakt door: org.springframework.beans.factory.UnsatisfiedDependencyException: Fout bij het aanmaken van bean met naam 'redisDao': Ontevreden afhankelijkheid uitgedrukt via veld ' redisTemplate'; Geneste uitzondering is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' beschikbaar: verwacht minstens 1 boon die als autowire-kandidaat in aanmerking komt. Afhankelijkheidsannotaties: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    op org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    op org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    op org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    op org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    op org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    op org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    op org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    op org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    op org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    op org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    op org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    op org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    op org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    op org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    op org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    op org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    op org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... 25 veelvoorkomende frames weggelaten
Veroorzaakt door: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' beschikbaar: verwacht minstens 1 boon die als autowire-kandidaat in aanmerking komt. Afhankelijkheidsannotaties: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    op 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)
    op org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 veelvoorkomende frames weggelaten
Het zien van dit grote foutlogboek is een beetje duizelig; we hoeven alleen maar naar de sleutelfoutlogs te kijken om het probleem te vinden. De tweede Veroorzaakt door in het foutlogboek print het sleutelfoutlogboek:No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

De auteur kijkt terug naar de geschreven code en specificeert het specifieke type bij het injecteren van RedisTemplate< K, V>.


Volgens het foutlogboek, controleer de code op regel 1493 van de klasse DefaultListableBeanFactory, de broncode is als volgt:

Deze twee methoden tonen aan dat geen enkele boon gematcht kan worden < RedisTemplate String, Object, >, dus hoe los je dit probleem op? Je kunt RedisTemplate< K, V> gebruiken zonder het specifieke type te specificeren, en de code als volgt aanpassen:

Herstart de service, er wordt geen fout gemeld in het opstartlogboek en de RedisTemplate injecteert de bean succesvol. Ik vraag me af waarom RedisTemplate< String, Object> injecting beans faalt. Na er lang over nagedacht te hebben, dacht ik dat RedisTemplate automatisch wordt geconfigureerd in het SpringBoot-framework, en dat de standaard in de container de instantie van RedisTemplate is. Met dit in gedachten moet je de officiële websitedocumenten doorzoeken om te zien of er een uitleg in de officiële websitedocumenten staat. En inderdaad, sectie 30.1.1 van de officiële documentatie legt RedisTemplate nog steeds uit.

Officieel documentadres:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Als je je eigen toevoegt@Beanvan alle auto-geconfigureerde types vervangt het de standaard (behalve in het geval van RedisTemplate, wanneer de uitsluiting gebaseerd is op de naam redisTemplate, niet op het type).
Als je je eigen bean toevoegt voor het autoconfiguratietype, vervangt die de standaard. Mijn code lijkt prima, wacht... Deze zin tussen haakjes is het punt. Vertaal een golf,Behalve in het geval van RedisTemplate, wanneer je uitsluit op basis van de naam van de boon, niet op het type. Het Engels is niet erg goed, en het lijkt erop dat de vertaling niet erg soepel is.

Nu lijkt het erop dat het RedisTemplate< String, Object > gebruikt @Autowired bij het injecteren,@Autowired standaard op type geassembleerd。 Met andere woorden, als je de bonen > RedisTemplate< String, Object wilt krijgen, moet je ze op basis van hun namen samenstellen. Denk dan natuurlijk aan het gebruiken ervan@Resource wordt het standaard geassembleerd volgens de naam。 Pas de code opnieuw aan als volgt:


De annotatie is veranderd van @Autowired naar @Resource Het project is foutloos gestart en het is perfect opgelost!

Herstart de service opnieuw, het opstartlogboek geeft geen foutmelding en de RedisTemplate< String, Object> injecteren de boon succesvol. Door deze fout heb ik een functie van de auto-configuratieklasse in het SpringBoot-framework geleerd. Tegelijkertijd weerspiegelt het ook dat het leren van een technologie vanaf de officiële website moet beginnen om te voorkomen dat je op de put stapt.
In het daadwerkelijke ontwikkelingsproces, met RedisTemplate< K, vereist V> geen specificatie van het type K en V, en kan de standaardboon aan de eisen voldoen.

Tot slot wil ik een klein probleem verifiëren en de code opnieuw aanpassen als volgt:


De bovenstaande code specificeert dat K en V beide stringtypes zijn bij het injecteren van RedisTemplate, en vergelijkt of redisTemplate en stringRedisTemplate hetzelfde object zijn in de compare()-methode. Voer de unit test-klasse uit en de testresultaten zijn als volgt:

2018-08-10 18:30:57.075 - Demo1ApplicationTests gestart in 15,58 seconden (JVM draait voor 16,974)
2018-08-10 18:30:57.360 - hashcode:1996087296 voor redisTemplate
2018-08-10 18:30:57.360 - stringRedisTemplate hashcode:1996087296
2018-08-10 18:30:57.363 - Resultaat van gelijk(): waar
2018-08-10 18:30:57.364 - Vergelijkingsresultaat van redisTemplate en stringRedisTemplate: waar
De testresultaten tonen aan dat redisTemplate en stringRedisTemplate hetzelfde object zijn. Wacht even... Waarom is het niet verkeerd om deze keer te specificeren dat K en V strings zijn bij het injecteren van RedisTemplate? Bovendien bleken de twee objecten hetzelfde object te zijn. Laten we eens kijken naar de broncode van StringRedisTemplate.

Na het lezen van de broncode, begrijp je het, want de ouderklasse van de StringRedisTemplate-klasse is RedisTemplate< String, String>, en de bean is standaard singleton, en de twee zijn van nature hetzelfde object.




Vorig:Uitgesproken naar waardetype "System.Decimaal" mislukt...
Volgend:Fout bij het aanmaken van bean met naam 'stringRedisTemplate' gedefinieerd in...
Disclaimer:
Alle software, programmeermaterialen of artikelen die door Code Farmer Network worden gepubliceerd, zijn uitsluitend bedoeld voor leer- en onderzoeksdoeleinden; De bovenstaande inhoud mag niet worden gebruikt voor commerciële of illegale doeleinden, anders dragen gebruikers alle gevolgen. De informatie op deze site komt van het internet, en auteursrechtconflicten hebben niets met deze site te maken. Je moet bovenstaande inhoud volledig van je computer verwijderen binnen 24 uur na het downloaden. Als je het programma leuk vindt, steun dan de echte software, koop registratie en krijg betere echte diensten. Als er sprake is van een inbreuk, neem dan contact met ons op via e-mail.

Mail To:help@itsvse.com