Αυτό το άρθρο είναι ένα άρθρο καθρέφτη της αυτόματης μετάφρασης, κάντε κλικ εδώ για να μεταβείτε στο αρχικό άρθρο.

Άποψη: 15336|Απάντηση: 0

[Πηγή] Η εξαίρεση επιλύεται με την εισαγωγή της παρουσίας RedisTemplate στο SpringBoot

[Αντιγραφή συνδέσμου]
Δημοσιεύτηκε στις 11/3/2019 1:25:56 μ.μ. | | | |
Πρόσφατα, το RedisTemplate χρησιμοποιήθηκε κατά την ανάπτυξη του έργου και η δοκιμή μονάδας ζήτησε "Το πεδίο redisTemplate στο com.example.demo1.dao.RedisDao απαιτούσε ένα φασόλι τύπου 'org.springframework.data.redis.core.RedisTemplate' που δεν ήταν δυνατή η εύρεση", το οποίο μεταφράζεται σε "δεν ήταν δυνατή η εύρεση ενός φασολιού τύπου RedisTemplate". Φυσικά, κοιτάζοντας μόνο αυτήν την πρόταση, δεν μπορούμε να είμαστε σίγουροι γιατί παρουσιάζεται αυτό το πρόβλημα. Τώρα, δημοσιεύστε ένα λεπτομερές αρχείο καταγραφής σφαλμάτων.

2018-08-10 14:53:49.761 - Εντοπίστηκε εξαίρεση ενώ επιτρέπεται στο TestExecutionListener [org.springframework.test.context.web.ServletTestExecutionListener@5af3afd9] να προετοιμάσει τη δοκιμή περίπτωση [com.example.demo1.Demo1ApplicationTests@2361365c]
java.lang.IllegalStateException: Failed to load ApplicationContext
    στο org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
    στο org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
    στο org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:189)
    στο org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:131)
    στο org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:287)
    στο org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    στο org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    στο org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    στο org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    στο org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    στο org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    στο org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    στο org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    στο org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    στο org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    στο org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    στο org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    στο org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    στο org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    στο org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    στο org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Προκαλείται από: org.springframework.beans.factory.UnsatisfactionDependencyException: Σφάλμα κατά τη δημιουργία φασολιού με όνομα 'redisDao': Μη ικανοποιημένη εξάρτηση που εκφράζεται μέσω του πεδίου ' redisTemplate»· ένθετη εξαίρεση είναι org.springframework.beans.factory.NoSuchBeanDefinitionException: Δεν υπάρχει προσδιοριστικό φασόλι τύπου 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' διαθέσιμο: αναμένεται τουλάχιστον 1 φασόλι που πληροί τις προϋποθέσεις ως υποψήφιο autowire. Σχόλια εξάρτησης: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    στο org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    στο org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    στο org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    στο org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    στο org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    στο org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    στο org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    στο org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    στο org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    στο org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    στο org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
    στο org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    στο org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
    στο org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
    στο org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
    στο org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    στο org.springframework.boot.test.context.SpringBootContextLoader.loader.loadContext(SpringBootContextLoader.java:120)
    στο org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
    στο org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
    ... Παραλείπονται 25 κοινά πλαίσια
Προκαλείται από: org.springframework.beans.factory.NoSuchBeanDefinitionException: Δεν υπάρχει κατάλληλο φασόλι τύπου 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>' διαθέσιμο: αναμένεται τουλάχιστον 1 φασόλι που πληροί τις προϋποθέσεις ως υποψήφιο autowire. Σχόλια εξάρτησης: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    στο org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
    στο org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
    στο org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    στο org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... Παραλείπονται 43 κοινά πλαίσια
Βλέποντας αυτό το μεγάλο αρχείο καταγραφής σφαλμάτων είναι λίγο ζαλισμένο, στην πραγματικότητα, χρειάζεται μόνο να δούμε τα βασικά αρχεία καταγραφής σφαλμάτων για να εντοπίσουμε το πρόβλημα. Το δεύτερο Caused by στο αρχείο καταγραφής σφαλμάτων εκτυπώνει το αρχείο καταγραφής σφαλμάτων κλειδιού:Δεν υπάρχει κατάλληλο φασόλι τύπου 'org.springframework.data.redis.core.RedisTemplate< java.lang.String, java.lang.Object>。

Ο συγγραφέας ανατρέχει στον κώδικα που γράφτηκε και καθορίζει τον συγκεκριμένο τύπο κατά την έγχυση του RedisTemplate< K, V>.


Σύμφωνα με το αρχείο καταγραφής σφαλμάτων, ελέγξτε τον κωδικό στη γραμμή 1493 της κλάσης DefaultListableBeanFactory, ο πηγαίος κώδικας είναι ο εξής:

Αυτές οι δύο μέθοδοι δείχνουν ότι κανένα φασόλι δεν μπορεί να αντιστοιχιστεί < RedisTemplate String, Object >, οπότε πώς να λύσετε αυτό το πρόβλημα; Μπορεί να θέλετε να χρησιμοποιήσετε το RedisTemplate< K, V> χωρίς να καθορίσετε τον συγκεκριμένο τύπο και να τροποποιήσετε τον κώδικα ως εξής:

Επανεκκινήστε την υπηρεσία, δεν αναφέρεται σφάλμα στο αρχείο καταγραφής εκκίνησης και το RedisTemplate εισάγει το φασόλι με επιτυχία. Αναρωτιέμαι γιατί αποτυγχάνει το RedisTemplate< String, Object> injecting beans. Αφού το σκέφτηκα για πολύ καιρό, σκέφτηκα ότι το RedisTemplate διαμορφώνεται αυτόματα στο πλαίσιο SpringBoot και η προεπιλογή στο κοντέινερ είναι η παρουσία του RedisTemplate. Σκεπτόμενος αυτό, πρέπει να ανατρέξετε στα έγγραφα του επίσημου ιστότοπου για να δείτε εάν υπάρχει κάποια εξήγηση στα έγγραφα του επίσημου ιστότοπου. Σίγουρα, η ενότητα 30.1.1 της επίσημης τεκμηρίωσης εξακολουθεί να εξηγεί το RedisTemplate.

Επίσημη διεύθυνση εγγράφου:https://docs.spring.io/spring-bo ... ference/htmlsingle/




Εάν προσθέσετε το δικό σας@Beanοποιουδήποτε από τους τύπους που ρυθμίζονται αυτόματα, αντικαθιστά την προεπιλογή (εκτός από την περίπτωση του RedisTemplate, όταν η εξαίρεση βασίζεται στο όνομα bean, redisTemplate, όχι στον τύπο του).
Εάν προσθέσετε το δικό σας φασόλι για τον τύπο αυτόματης διαμόρφωσης, θα αντικαταστήσει το προεπιλεγμένο. Ο κωδικός μου φαίνεται να είναι μια χαρά, περίμενε... Αυτή η πρόταση σε παρένθεση είναι το θέμα. Μεταφράστε ένα κύμα,Εκτός από την περίπτωση του RedisTemplate, όταν εξαιρείται με βάση το όνομα του φασολιού και όχι τον τύπο του. Τα αγγλικά δεν είναι πολύ καλά και φαίνεται ότι η μετάφραση δεν είναι πολύ ομαλή.

Τώρα φαίνεται να είναι κατανοητό ότι το RedisTemplate< String, Object > χρησιμοποιηθεί @Autowired κατά την έγχυση,@Autowired συναρμολογείται ανά τύπο από προεπιλογή。 Με άλλα λόγια, εάν θέλετε να πάρετε τα φασόλια > RedisTemplate< String, Object, πρέπει να τα συναρμολογήσετε σύμφωνα με τα ονόματά τους. Τότε φυσικά σκεφτείτε να το χρησιμοποιήσετε@Resource, συναρμολογείται από προεπιλογή σύμφωνα με το όνομα。 Τροποποιήστε ξανά τον κώδικα ως εξής:


Ο σχολιασμός έχει αλλάξει από @Autowired σε @Resource Το έργο ξεκίνησε χωρίς λάθος και λύθηκε τέλεια!

Επανεκκινήστε ξανά την υπηρεσία, το αρχείο καταγραφής εκκίνησης δεν αναφέρει σφάλμα και το RedisTemplate< String, Object> εισάγει το φασόλι με επιτυχία. Μέσω αυτού του σφάλματος, έμαθα μια δυνατότητα της κλάσης αυτόματης διαμόρφωσης στο πλαίσιο SpringBoot. Ταυτόχρονα, αντικατοπτρίζει επίσης ότι η εκμάθηση μιας τεχνολογίας πρέπει να ξεκινά από τον επίσημο ιστότοπο για να αποφευχθεί το πάτημα στο λάκκο.
Στην πραγματική διαδικασία ανάπτυξης, χρησιμοποιώντας το RedisTemplate< τα K, V> δεν απαιτούν τον καθορισμό του τύπου K και V και το προεπιλεγμένο φασόλι μπορεί να πληροί τις απαιτήσεις.

Τέλος, θέλω να επαληθεύσω ένα μικρό πρόβλημα και να τροποποιήσω ξανά τον κώδικα ως εξής:


Ο παραπάνω κώδικας καθορίζει ότι το K και το V είναι και οι δύο τύποι συμβολοσειράς κατά την έγχυση του RedisTemplate και συγκρίνει εάν το redisTemplate και το stringRedisTemplate είναι το ίδιο αντικείμενο στη μέθοδο compare(). Εκτελέστε την κατηγορία δοκιμής μονάδας και τα αποτελέσματα της δοκιμής είναι τα εξής:

2018-08-10 18:30:57.075 - Ξεκίνησε το Demo1ApplicationTests σε 15.58 δευτερόλεπτα (το JVM εκτελείται για 16.974)
2018-08-10 18:30:57.360 - hashcode:1996087296 για redisTemplate
2018-08-10 18:30:57.360 - stringRedisTemplate κωδικός κατακερματισμού:1996087296
2018-08-10 18:30:57.363 - Αποτέλεσμα equal(): true
2018-08-10 18:30:57.364 - Αποτέλεσμα σύγκρισης των redisTemplate και stringRedisTemplate: true
Τα αποτελέσματα των δοκιμών δείχνουν ότι το redisTemplate και το stringRedisTemplate είναι το ίδιο αντικείμενο. Περίμενε ένα λεπτό... Γιατί δεν είναι λάθος να διευκρινιστεί ότι τα K και V είναι συμβολοσειρές κατά την έγχυση του RedisTemplate αυτή τη φορά; Επιπλέον, τα δύο αντικείμενα αποδείχθηκαν το ίδιο αντικείμενο. Ας ρίξουμε μια ματιά στον πηγαίο κώδικα του StringRedisTemplate.

Αφού διαβάσετε τον πηγαίο κώδικα, καταλαβαίνετε, επειδή η γονική κλάση της κλάσης StringRedisTemplate είναι RedisTemplate< String, String> και το φασόλι είναι singleton από προεπιλογή και τα δύο είναι φυσικά το ίδιο αντικείμενο.




Προηγούμενος:Η μετάδοση στον τύπο τιμής "System.Decimal" απέτυχε...
Επόμενος:Σφάλμα κατά τη δημιουργία φασολιών με το όνομα 'stringRedisTemplate' που ορίζεται στο...
Αποκήρυξη:
Όλο το λογισμικό, το υλικό προγραμματισμού ή τα άρθρα που δημοσιεύονται από το Code Farmer Network προορίζονται μόνο για μαθησιακούς και ερευνητικούς σκοπούς. Το παραπάνω περιεχόμενο δεν θα χρησιμοποιηθεί για εμπορικούς ή παράνομους σκοπούς, άλλως οι χρήστες θα υποστούν όλες τις συνέπειες. Οι πληροφορίες σε αυτόν τον ιστότοπο προέρχονται από το Διαδίκτυο και οι διαφορές πνευματικών δικαιωμάτων δεν έχουν καμία σχέση με αυτόν τον ιστότοπο. Πρέπει να διαγράψετε εντελώς το παραπάνω περιεχόμενο από τον υπολογιστή σας εντός 24 ωρών από τη λήψη. Εάν σας αρέσει το πρόγραμμα, υποστηρίξτε γνήσιο λογισμικό, αγοράστε εγγραφή και λάβετε καλύτερες γνήσιες υπηρεσίες. Εάν υπάρχει οποιαδήποτε παραβίαση, επικοινωνήστε μαζί μας μέσω email.

Mail To:help@itsvse.com