Nedavno je bil RedisTemplate uporabljen med razvojem projekta, enotsko testiranje pa je spodbudilo "Field redisTemplate in com.example.demo1.dao.RedisDao je zahteval zrno tipa 'org.springframework.data.redis.core.RedisTemplate', ki je zahtevalo zrno tipa 'org.springframework.data.redis.core.RedisTemplate', ki je zahtevalo 'Field redisTemplate in com.example.demo1.dao.RedisDao ni bilo mogoče najti", kar pomeni "ni bilo mogoče najti zrna tipa RedisTemplate". Seveda, če pogledamo samo ta stavek, ne moremo biti prepričani, zakaj se ta problem pojavi. Zdaj objavite podroben dnevnik napak.
2018-08-10 14:53:49.761 - Ujeti izjemo, ko je TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] omogočil pripravo testa Primer [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext na org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) na org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189) na org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131) na 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 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 og.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) na 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) na org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Vzrok: org.springframework.beans.factory.UnsatisfiedDependencyException: Napaka pri ustvarjanju zrna z imenom 'redisDao': Nezadovoljena odvisnost izražena preko polja ' redisTemplate'; gnezdena izjema je org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean tipa 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' na voljo: pričakovano vsaj 1 fižol, ki izpolnjuje pogoje za avtomatsko žico. Oznake odvisnosti: {@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) na 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) na org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) na org.springframework.boot.SpringApplication.run(SpringApplication.java:303) na 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 pogostih okvirjev izpuščenih Vzrok: org.springframework.beans.factory.NoSuchBeanDefinitionException: Ni kvalificiranega beana tipa 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' na voljo: pričakovano vsaj 1 fižol, ki izpolnjuje pogoje za avtomatsko žico. Oznake odvisnosti: {@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 pogostih okvirjev izpuščenih Videti ta velik dnevnik napak je nekoliko zmedeno, pravzaprav moramo le pogledati ključne zapise napak, da najdemo težavo. Drugi Caused by v dnevniku napak napiše ključ v dnevniku napak:No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。
Avtor se ozre nazaj na napisano kodo in določi specifično vrsto pri vbrizgavanju RedisTemplate< K, V>.
Po dnevniku napak preverite kodo na vrstici 1493 razreda DefaultListableBeanFactory, izvorna koda je naslednja:
Ti dve metodi kažeta, da nobena ni mogoče ujeti < RedisTemplate String, Object >, kako torej rešiti ta problem? Morda boste želeli uporabiti RedisTemplate< K, V> brez natančnega tipa in spremeniti kodo na naslednji način:
Ponovni zagon storitve, v zagonskem dnevniku ni prijavljena nobena napaka, RedisTemplate pa uspešno vbrizga zrno. Sprašujem se, zakaj RedisTemplate< String, Object> vbrizgavanje zrn ne uspe. Po dolgem premisleku sem ugotovil, da je RedisTemplate samodejno konfiguriran v SpringBoot ogrodju, privzeta pa je instanca RedisTemplate. Glede na to morate pregledati uradne dokumente na spletni strani, da preverite, ali je v njih kakšna razlaga. In res, oddelek 30.1.1 uradne dokumentacije še vedno pojasnjuje RedisTemplate.
Uradni naslov dokumenta:https://docs.spring.io/spring-bo ... ference/htmlsingle/
Če dodaš svoje@Beanod vseh samodejno konfiguriranih vrst nadomesti privzeto (razen v primeru RedisTemplate, kjer je izključitev osnovana na imenu zrna, redisTemplate, ne na njegovi vrsti). Če dodaš svoje zrno za tip samodejne konfiguracije, bo nadomestilo privzeto. Moja koda se zdi v redu, počakaj... Ta stavek v oklepaju je bistvo. Prevedi val,Razen v primeru RedisTemplate, ko izključujemo na podlagi imena zrna, ne vrste. Angleščina ni najboljša in zdi se, da prevod ni ravno gladek.
Zdaj se zdi, da je razumljeno, da > RedisTemplate< String, Object uporabljen @Autowired pri vbrizgavanju,@Autowired privzeto sestavljeno po tipu。 Z drugimi besedami, če želite dobiti zrna > RedisTemplate< String, Object, jih morate sestaviti glede na njihova imena. Potem seveda pomislite na njegovo uporabo@Resource je sestavljena privzeto glede na ime。 Kodo ponovno spremenite na naslednji način:
Opombe so spremenile iz @Autowired v @Resource Projekt se je začel brez napake in bil je popolnoma rešen!
Če storitev ponovno zaženete, zagonski dnevnik ne poroča o napaki, RedisTemplate< String, Object> uspešno vbrizga zrno. S to napako sem se naučil funkcije razreda samodejne konfiguracije v ogrodju SpringBoot. Hkrati pa odraža, da bi se znanje tehnologije moralo začeti na uradni spletni strani, da se izognete stopanju na jamo. V dejanskem razvojnem procesu z uporabo RedisTemplate< K, V> ne zahteva določanja vrste K in V, privzeti zrno pa lahko izpolnjuje zahteve.
Na koncu želim preveriti majhen problem in ponovno spremeniti kodo na naslednji način:
Zgornja koda določa, da sta K in V oba tipa nizov pri vbrizgavanju RedisTemplate in primerja, ali sta redisTemplate in stringRedisTemplate isti objekt v metodi compare(). Zaženite razred enotskega testa in rezultati testa so naslednji:
2018-08-10 18:30:57.075 - Začetek Demo1ApplicationTests v 15,58 sekundah (JVM teče 16,974) 2018-08-10 18:30:57.360 - hashcode:1996087296 for redisTemplate 2018-08-10 18:30:57.360 - stringRedisTemplate hashcode:1996087296 2018-08-10 18:30:57.363 - Rezultat equal(): true 2018-08-10 18:30:57.364 - Primerjalni rezultat redisTemplate in stringRedisTemplate: true Rezultati testa kažejo, da sta redisTemplate in stringRedisTemplate isti objekt. Samo malo... Zakaj ni narobe, če tokrat pri vbrizgavanju RedisTemplate navedemo, da sta K in V nizi? Poleg tega sta se izkazala za ista predmeta. Poglejmo izvorno kodo StringRedisTemplate.
Po branju izvorne kode, razumete, ker je nadrejen razred razreda StringRedisTemplate RedisTemplate< String, String>, in bean je privzeto singleton, in oba sta naravno isti objekt.
|