spring @在构造函数上自动连接(必需=false),给出NoSuchBeanDefinitionException

dsf9zpds  于 2022-10-30  发布在  Spring
关注(0)|答案(3)|浏览(135)

在一个Spring应用程序中,我在构造函数上使用了@Autowired(required=false)。这意味着如果要自动连接的bean在xml文件中不可用,则不会抛出NoSuchBeanDefinitionException,因为提到了(required=false)。但是我得到了UnsatisfiedDependencyExceptionNoSuchBeanDefinitionException异常。
----文本编辑器

  1. public class TextEditor {
  2. private SpellChecker x;
  3. private String name;
  4. @Autowired(required=false)
  5. public TextEditor(SpellChecker x) {
  6. System.out.println("Inside TextEditor constructor." );
  7. this.x = x;
  8. }
  9. public SpellChecker getY() {
  10. return x;
  11. }
  12. public void setName(String name) {
  13. this.name = name;
  14. }
  15. public String getName() {
  16. return name;
  17. }
  18. public void spellCheck() {
  19. x.checkSpelling();
  20. }
  21. }

----拼字检查程式

  1. public class SpellChecker {
  2. public SpellChecker() {
  3. System.out.println("Inside SpellChecker constructor.");
  4. }
  5. public void checkSpelling() {
  6. System.out.println("Inside checkSpelling.");
  7. }
  8. }

----Bean文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:aks="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
  4. aks:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. http://www.springframework.org/schema/context
  7. http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  8. <context:annotation-config />
  9. <bean id="textEditor" class="com.tutorialspoint.TextEditor">
  10. <!-- <property name="x" ref="a" /> -->
  11. <property name="name" value="Generic Text Editor" />
  12. </bean>
  13. <!-- <bean id="a" class="com.tutorialspoint.SpellChecker" /> -->
  14. </beans>
  15. ---- MainApp
  16. public class MainApp {
  17. public static void main(String[] args) {
  18. ApplicationContext context = new ClassPathXmlApplicationContext(
  19. "Beans.xml");//Beans.xml, Beans1.xml
  20. TextEditor te = (TextEditor) context.getBean("textEditor");
  21. //te.spellCheck();
  22. System.out.println(te.getY());
  23. }
  24. }

---控制台(实际结果)

  1. Apr 24, 2014 4:30:00 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
  2. INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@15eb0a9: startup date [Thu Apr 24 16:30:00 IST 2014]; root of context hierarchy
  3. Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
  4. INFO: Loading XML bean definitions from class path resource [Beans.xml]
  5. Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
  6. INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2d9c06: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,textEditor]; root of factory hierarchy
  7. Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
  8. INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2d9c06: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,textEditor]; root of factory hierarchy
  9. Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'textEditor' defined in class path resource [Beans.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [com.tutorialspoint.SpellChecker]: : No matching bean of type [com.tutorialspoint.SpellChecker] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.tutorialspoint.SpellChecker] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
  10. at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
  11. at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
  12. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1002)
  13. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:906)
  14. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:484)
  15. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
  16. at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
  17. at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
  18. at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
  19. at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
  20. at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
  21. at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
  22. at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
  23. at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
  24. at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
  25. at com.tutorialspoint.MainApp.main(MainApp.java:8)
  26. Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.tutorialspoint.SpellChecker] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
  27. at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
  28. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
  29. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
  30. at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
  31. at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
  32. ... 15 more

---预期结果程序应该在没有任何Exception的情况下运行,因为构造函数中提到了@Autowire(required=false)。即使没有找到bean,也不应该出现异常,因为提到了(required=false)。

xxb16uws

xxb16uws1#

这个异常的发生是因为required = false并不意味着它将注入null。当应用于构造函数时,Spring将尝试决定哪个构造函数最适合创建示例。在这种情况下,只有一个构造函数需要拼写检查器,但没有该类型的对象。
如Spring文档(http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html)中所述:
任何给定Bean类只能有一个构造函数(最多一个)带有此注解,指示用作Spring Bean时要自动连接的构造函数。这样的构造函数不必是公共的。
无论如何,你可以添加一个默认的构造函数(它可以是私有的),这样当Spring不能使用它的@Autowired魔法时,它就会使用那个。在TextEditor类中,你可以添加:

  1. @Deprecated
  2. private TextEditor() {
  3. // You could leave x = null or create a default value for that field
  4. // if you have one (eg. x = new DefaultSpellChecker();)
  5. }

请注意,使用@Deprecated是为了避免编译器警告您有一个没有人使用的私有构造函数。

c9qzyr3d

c9qzyr3d2#

我也遇到过类似的问题。实际上,可以有几个构造函数

  1. @Autowired(required = false)

但是,请注意,您不能在默认(不带参数)构造函数上添加此注解,因为@Autowired注解至少需要一个参数

mzillmmw

mzillmmw3#

虽然@Nicola提到的方法是正确的,但是您必须有多个构造函数,这样spring才能根据参数选择正确的构造函数。不过,如果您希望SpellChecker参数为null,并且出于某种原因不希望有额外的构造函数,您也可以将其定义为可为null,但是您必须在使用SpellChecker示例的任何地方保持null检查。

  1. @Autowired(required=false)
  2. public TextEditor(@Nullable SpellChecker x) {

相关问题