Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 15336|Yanıt: 0

[Kaynak] İstisna, SpringBoot'ta RedisTemplate örneği enjekte edilmesiyle çözülür

[Bağlantıyı kopyala]
Yayınlandı 11.03.2019 13:25:56 | | | |
Son zamanlarda proje geliştirme sırasında RedisTemplate kullanıldı ve birim testi "com.example.demo1.dao.RedisDao içindeki redisTemplate alanı, 'org.springframework.data.redis.core.RedisTemplate' tipinde bir bean gerektiriyordu bulunamadı" anlamına gelir, bu da "RedisTemplate tipi bir çekirdek bulamadım" anlamına gelir. Tabii ki, sadece bu cümleye bakarak bu sorunun neden ortaya çıktığından emin olamıyoruz. Şimdi, detaylı bir hata kaydı paylaşın.

2018-08-10 14:53:49.761 - TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] testi hazırlamasına izin verirken istisna yakaladı örnek [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189) adresinde
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) adresinde
    org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) adresinde
    org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) adresinde
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) adresinde
    org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) adresinde
    org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) adresinde
    org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) adresinde
    org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) adresinde
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    org.junit.runners.ParentRunner.run(ParentRunner.java:363) adresinde
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) adresinde
    org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) adresinde
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) adresinde
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) adresinde
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) adresinde
    org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) adresinde
Nedeni: org.springframework.beans.factory.UnsatisfiedDependencyException: 'redisDao' adlı fasulye oluşturma hatası: Alan ' aracılığıyla ifade edilen tatmin edilmemiş bağımlılık redisTemplate'; iç içe istisna org.springframework.beans.factory.NoSuchBeanDefinitionException: 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object' tipinde nitelikli bir çekirdek yoktur>' Kullanılabilir: En az 1 fasulye bekleniyor ve bu otomatik kablo adayı olarak nitelendiriliyor. Bağımlılık annotasyonları: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) adresinde
    org.springframework.beans.factory.annotation.injectionMetadata.inject(InjectionMetadata.java:88) adresinde
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) adresinde
    org.springframework.beans.factory.support.abstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) adresinde
    org.springframework.beans.factory.support.abstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553) adresinde
    org.springframework.beans.factory.support.abstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483) adresinde
    org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) adresinde
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) adresinde
    org.springframework.beans.factory.support.abstractBeanFactory.getBean(AbstractBeanFactory.java:197) adresinde
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) adresinde
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543) adresinde
    org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) adresinde
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at 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 yaygın çerçeve çıkarıldı
Nedeni: org.springframework.beans.factory.NoSuchBeanDefinitionException: 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object' tipinde nitelikli bir çekirdek yok>' Kullanılabilir: En az 1 fasulye bekleniyor ve bu otomatik kablo adayı olarak nitelendiriliyor. Bağımlılık annotasyonları: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493) adresinde
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585) adresinde
    ... 43 yaygın çerçeve çıkarıldı
Bu büyük hata günlüğünü görmek biraz baş döndürücü, aslında sorunu bulmak için sadece anahtar hata kayıtlarına bakmamız yeterli. İkinci Caused by hata logunda anahtar hata günlüğünü yazdırır:'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。 tipinde bir niteleyici bean yok

Yazar, yazılmış kodu tekrar bakar ve RedisTemplate< K, V> enjekte ederken belirli tipi belirtir.


Hata günlüğüne göre, DefaultListableBeanFactory sınıfının 1493 satırındaki kodu kontrol edin, kaynak kodu şu şekildedir:

Bu iki yöntem, hiçbir fasulyeyin RedisTemplate Dizisi, Nesne, > < eşleşemeyeceğini gösteriyor, peki bu sorunu nasıl çözebilirim? RedisTemplate< K, V> kullanmayı ve kodu aşağıdaki gibi değiştirmeyi tercih edebilirsiniz:

Hizmeti yeniden başlatın, başlangıç günlüğünde hata bildirilmez ve RedisTemplate çekirdeki başarıyla enjekte eder. RedisTemplate< String, Object> çekirdek enjekte etmenin neden başarısız olduğunu merak ediyorum. Uzun düşündükten sonra, RedisTemplate'in SpringBoot framework'te otomatik olarak yapılandırıldığını ve konteynerdeki varsayılan olarak RedisTemplate örneği olduğunu düşündüm. Bunu düşününce, resmi web sitesi belgelerinde herhangi bir açıklama olup olmadığını görmek için resmi web sitesi belgelerini gözden geçirmeniz gerekir. Gerçekten de, resmi dokümantasyonun 30.1.1 bölümü hâlâ RedisTemplate'i açıklıyor.

Resmi belge adresi:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Kendi ekinizi eklerseniz@Beanotomatik yapılandırılan tiplerin herhangi birinden varsayılanı değiştirir (RedisTemplate hariç, hariç tutma bean adı olan redisTemplate'e dayanır, tipine değil).
Otomatik yapılandırma türü için kendi bean'inizi eklerseniz, varsayılan olanı değiştirir. Kodum iyi görünüyor, bekle... Parantez içindeki bu cümle asıl nokta. Bir dalgayı çevir,RedisTemplate hariç, hariç hariç olarak, fasulyenin adına göre hariç tutulurken, tipine değil. İngilizce çok iyi değil ve çeviri de pek akıcı değil gibi görünüyor.

Şimdi anlaşıldığı anlaşılıyor ki RedisTemplate< Dizisi, Nesne > enjekte edilirken @Autowired kullanılıyor,@Autowired varsayılan olarak tipe göre derlenir。 Başka bir deyişle, çekirdekleri RedisTemplate< String, Object > almak istiyorsanız, onları isimlerine göre birleştirmeniz gerekir. O zaman doğal olarak kullanmayı düşün@Resource, ismine göre varsayılan olarak birleştirilir。 Kodu tekrar aşağıdaki gibi değiştirin:


Annotasyon @Autowired'dan @Resource'a değiştirildi. Proje hatasız başladı ve mükemmel şekilde çözüldü!

Hizmeti tekrar başlatın, başlangıç günlüğü hata rapor etmez ve RedisTemplate< String, Object> çekirdeki başarıyla enjekte eder. Bu hata sayesinde, SpringBoot framework'teki otomatik yapılandırma sınıfının bir özelliğini öğrendim. Aynı zamanda, bir teknolojiyi öğrenmenin resmi web sitesinden başlaması gerektiğini, çukura basmaktan kaçınması gerektiğini de yansıtıyor.
Gerçek geliştirme sürecinde, RedisTemplate< K kullanılarak V> K ve V türlerini belirtmek zorunda kalmaz ve varsayılan çekirdek gereksinimleri karşılayabilir.

Son olarak, küçük bir sorunu doğrulamak ve kodu tekrar şu şekilde değiştirmek istiyorum:


Yukarıdaki kod, RedisTemplate enjekte edilirken K ve V'nin her ikisinin de String tipi olduğunu belirtir ve compare() yönteminde redisTemplate ile stringRedisTemplate'in aynı nesne olup olmadığını karşılaştırır. Birim test sınıfını çalıştırın, test sonuçları aşağıdaki gibidir:

2018-08-10 18:30:57.075 - Demo1ApplicationTests 15.58 saniyede başladı (JVM 16.974 saniyede çalışıyor)
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 - Eşit(): doğru sonucu
2018-08-10 18:30:57.364 - redisTemplate ile stringRedisTemplate'in karşılaştırma sonucu doğrudur
Test sonuçları, redisTemplate ve stringRedisTemplate'in aynı nesne olduğunu gösteriyor. Bir dakika bekle... Bu sefer RedisTemplate enjekte edilirken K ve V'nin String olduğunu belirtmek neden yanlış değil? Ayrıca, iki nesne aynı nesne çıktı. StringRedisTemplate'in kaynak koduna bir göz atalım.

Kaynak kodunu okuduktan sonra anladınız mı, çünkü StringRedisTemplate sınıfının ana sınıfı RedisTemplate< String, String> ve çekirdek varsayılan olarak singleton, ayrıca ikisi doğal olarak aynı nesne.




Önceki:"System.Decimal" değer türüne döküm başarısız oldu...
Önümüzdeki:'stringRedisTemplate' adıyla tanımlanmış bir çekirdek oluşturma hatası var...
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com