Šis raksts ir mašīntulkošanas spoguļraksts, lūdzu, noklikšķiniet šeit, lai pārietu uz oriģinālo rakstu.

Skats: 15336|Atbildi: 0

[Avots] Izņēmums tiek novērsts, injicējot RedisTemplate instanci programmā SpringBoot

[Kopēt saiti]
Publicēts 11.03.2019 13:25:56 | | | |
Nesen projekta izstrādes laikā tika izmantots RedisTemplate, un vienības testēšana pamudināja "Field redisTemplate com.example.demo1.dao.RedisDao prasīja pupiņu ar tipu "org.springframework.data.redis.core.RedisTemplate", kas nevarēja atrast", kas tulkojumā nozīmē "nevarēja atrast RedisTemplate tipa pupiņu". Protams, aplūkojot tikai šo teikumu, mēs nevaram būt pārliecināti, kāpēc šī problēma rodas. Tagad ievietojiet detalizētu kļūdu žurnālu.

2018-08-10 14:53:49.761 - Noķerts izņēmums, ļaujot TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] sagatavot testu gadījums [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    vietnē org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    vietnē org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    vietnē org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    vietnē org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    vietnē org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    vietnē org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    vietnē org.junit.runners.ParentRunner$1.grafiks(ParentRunner.java:71)
    vietnē org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    vietnē org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    vietnē org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    vietnē org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    vietnē org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    vietnē org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    vietnē org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    vietnē org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    vietnē org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    vietnē org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    vietnē org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    vietnē org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Izraisījis: org.springframework.beans.factory.UnsatisfiedDependencyException: Kļūda, veidojot pupiņas ar nosaukumu 'redisDao': Neapmierināta atkarība, kas izteikta ar lauku ' redisTemplate"; ligzdotais izņēmums ir org.springframework.beans.factory.NoSuchBeanDefinitionException: nav kvalificētas pupiņas ar tipu 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' pieejams: sagaidāms vismaz 1 pupiņa, kas kvalificējas kā autowire kandidāts. Atkarības anotācijas: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    vietnē org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    vietnē org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    vietnē org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    vietnē org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    vietnē org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    vietnē org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    vietnē org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    vietnē org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    vietnē org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    vietnē org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    vietnē org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    vietnē org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    vietnē org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    vietnē org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    vietnē org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    vietnē org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    vietnē org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
    vietnē org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    vietnē org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... Izlaisti 25 izplatītākie kadri
Cēlonis: org.springframework.beans.factory.NoSuchBeanDefinitionException: Nav kvalificētas pupiņas ar tipu 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' pieejams: sagaidāms vismaz 1 pupiņa, kas kvalificējas kā autowire kandidāts. Atkarības anotācijas: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    vietnē org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
    vietnē org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    vietnē org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    vietnē org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 43 izplatītākie kadri izlaisti
Redzot šo lielo kļūdu žurnālu, ir nedaudz reibonis, patiesībā mums ir jāapskata tikai galvenie kļūdu žurnāli, lai atrastu problēmu. Otrais Cēlonis kļūdu žurnālā izdrukā galveno kļūdu žurnālu:Nav kvalificējošu pupiņu tipa 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

Autors atskatās uz uzrakstīto kodu un norāda konkrēto veidu, injicējot RedisTemplate< K, V>.


Saskaņā ar kļūdu žurnālu pārbaudiet kodu klases DefaultListableBeanFactory 1493. rindā, avota kods ir šāds:

Šīs divas metodes parāda, ka nevienu pupiņu nevar saskaņot < RedisTemplate virkni, objektu >, tātad, kā atrisināt šo problēmu? Jūs varat izmantot RedisTemplate< K, V> nenorādot konkrēto tipu, un modificēt kodu šādi:

Restartējiet pakalpojumu, startēšanas žurnālā netiek ziņots par kļūdu, un RedisTemplate veiksmīgi injicē pupiņu. Nez, kāpēc neizdodas RedisTemplate< String, Object> pupiņu injicēšana. Ilgi domājot par to, es domāju, ka RedisTemplate tiek automātiski konfigurēts SpringBoot ietvarā, un konteinera noklusējums ir RedisTemplate instance. Domājot par to, jums ir jāpārskata oficiālie vietnes dokumenti, lai redzētu, vai oficiālajos tīmekļa vietnes dokumentos ir kāds paskaidrojums. Protams, oficiālās dokumentācijas 30.1.1. sadaļā joprojām ir izskaidrots RedisTemplate.

Oficiālā dokumenta adrese:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Ja pievienojat savu@Beanno jebkura automātiski konfigurētā tipa tas aizstāj noklusējuma (izņemot RedisTemplate gadījumu, kad izslēgšana ir balstīta uz pupiņu nosaukumu redisTemplate, nevis tā tipu).
Ja automātiskās konfigurācijas tipam pievienojat savu pupiņu, tas aizstās noklusējuma. Šķiet, ka mans kods ir labi, pagaidiet... Šis teikums iekavās ir punkts. Tulkot vilni,Izņemot RedisTemplate gadījumu, izslēdzot, pamatojoties uz pupiņu nosaukumu, nevis veidu. Angļu valoda nav ļoti laba, un šķiet, ka tulkojums nav ļoti gluds.

Tagad šķiet, ka ir saprotams, ka RedisTemplate< virkne, objekts > izmantots @Autowired, injicējot,@Autowired pēc noklusējuma samontēts pēc tipa。 Citiem vārdiem sakot, ja vēlaties iegūt pupiņas > RedisTemplate< String, Object, jums tās jāsaliek atbilstoši to nosaukumiem. Tad, protams, padomājiet par tā izmantošanu@Resource tas pēc noklusējuma tiek samontēts saskaņā ar nosaukumu。 Vēlreiz modificējiet kodu šādi:


Anotācija ir mainīta no @Autowired uz @Resource Projekts sākās bez kļūdām, un tas tika lieliski atrisināts!

Restartējiet pakalpojumu vēlreiz, startēšanas žurnāls neziņo par kļūdu, un RedisTemplate< virkne, objekts> veiksmīgi injicē pupiņu. Izmantojot šo kļūdu, es uzzināju automātiskās konfigurācijas klases funkciju SpringBoot ietvarā. Tajā pašā laikā tas arī atspoguļo, ka tehnoloģijas apguve jāsāk no oficiālās vietnes, lai izvairītos no kāpšanas uz bedres.
Faktiskajā izstrādes procesā, izmantojot RedisTemplate< K, V> nav nepieciešams norādīt K un V tipu, un noklusējuma pupiņas var atbilst prasībām.

Visbeidzot, es vēlos pārbaudīt nelielu problēmu un vēlreiz modificēt kodu šādi:


Iepriekš minētais kods norāda, ka K un V ir virknes tipi, injicējot RedisTemplate, un salīdzina, vai redisTemplate un stringRedisTemplate ir viens un tas pats objekts compare() metodē. Palaidiet vienības testa klasi, un testa rezultāti ir šādi:

2018-08-10 18:30:57.075 - Sāka Demo1ApplicationTests 15.58 sekundēs (JVM darbojas 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 - Rezultāts equal(): true
2018-08-10 18:30:57.364 - redisTemplate un stringRedisTemplate salīdzināšanas rezultāts: true
Testa rezultāti rāda, ka redisTemplate un stringRedisTemplate ir viens un tas pats objekts. Pagaidi minūti... Kāpēc nav nepareizi norādīt, ka K un V ir virknes, šoreiz injicējot RedisTemplate? Turklāt abi objekti izrādījās viens un tas pats objekts. Apskatīsim StringRedisTemplate avota kodu.

Pēc avota koda izlasīšanas, vai jūs saprotat, jo StringRedisTemplate klases vecākklase ir RedisTemplate< String, String>, un pupiņa pēc noklusējuma ir singleton, un abi dabiski ir viens un tas pats objekts.




Iepriekšējo:Apraide uz vērtības tipu "System.Decimal" neizdevās...
Nākamo:Kļūda, veidojot pupiņas ar nosaukumu 'stringRedisTemplate', kas definēts...
Atruna:
Visa programmatūra, programmēšanas materiāli vai raksti, ko publicē Code Farmer Network, ir paredzēti tikai mācību un pētniecības mērķiem; Iepriekš minēto saturu nedrīkst izmantot komerciāliem vai nelikumīgiem mērķiem, pretējā gadījumā lietotājiem ir jāuzņemas visas sekas. Informācija šajā vietnē nāk no interneta, un autortiesību strīdiem nav nekāda sakara ar šo vietni. Iepriekš minētais saturs ir pilnībā jāizdzēš no datora 24 stundu laikā pēc lejupielādes. Ja jums patīk programma, lūdzu, atbalstiet oriģinālu programmatūru, iegādājieties reģistrāciju un iegūstiet labākus oriģinālus pakalpojumus. Ja ir kādi pārkāpumi, lūdzu, sazinieties ar mums pa e-pastu.

Mail To:help@itsvse.com