构造函数上的@Autowired(required = false)给出NoSuchBeanDefinitionException [英] @Autowired(required=false) on constructor giving NoSuchBeanDefinitionException

查看:102
本文介绍了构造函数上的@Autowired(required = false)给出NoSuchBeanDefinitionException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Spring应用程序中,我在构造函数上使用了@Autowired(required=false).这意味着,如果要自动装配的Bean在xml文件中不可用,则不会抛出任何NoSuchBeanDefinitionException,因为提到了(required=false).但是我遇到了UnsatisfiedDependencyExceptionNoSuchBeanDefinitionException异常.

In a Spring application, I have used @Autowired(required=false) on constructor. This means that if the bean that will be autowired is not available in the xml file, no NoSuchBeanDefinitionException should be thrown as (required=false) is mentioned. But I am getting the UnsatisfiedDependencyException, NoSuchBeanDefinitionException exception.

---- TextEditor

---- TextEditor

public class TextEditor {

    private SpellChecker x;
    private String name;    

    @Autowired(required=false)
    public TextEditor(SpellChecker x) {
        System.out.println("Inside TextEditor constructor." );
        this.x = x;
    }


    public SpellChecker getY() {
        return x;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void spellCheck() {
        x.checkSpelling();
    }
}

----拼写检查器

public class SpellChecker {
    public SpellChecker() {
        System.out.println("Inside SpellChecker constructor.");
    }

    public void checkSpelling() {
        System.out.println("Inside checkSpelling.");
    }
}

---- Beans.xml

---- Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:aks="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    aks:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />

    <bean id="textEditor" class="com.tutorialspoint.TextEditor">
        <!-- <property name="x" ref="a" /> -->
        <property name="name" value="Generic Text Editor" />
    </bean>

    <!-- <bean id="a" class="com.tutorialspoint.SpellChecker" /> -->

</beans>

---- MainApp
public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "Beans.xml");//Beans.xml, Beans1.xml
        TextEditor te = (TextEditor) context.getBean("textEditor");
        //te.spellCheck();
        System.out.println(te.getY());
    }
}

-控制台(实际结果)

Apr 24, 2014 4:30:00 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@15eb0a9: startup date [Thu Apr 24 16:30:00 IST 2014]; root of context hierarchy
Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [Beans.xml]
Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
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
Apr 24, 2014 4:30:00 PM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
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
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: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1002)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:906)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:484)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:455)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.tutorialspoint.MainApp.main(MainApp.java:8)
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: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:924)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:793)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
    ... 15 more

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

--- Expected Result Program should run without any Exception as @Autowire(required=false) is mentioned for the constructor. Even if the bean is not found the exception should not come since (required=false) is mentioned.

推荐答案

发生此异常是因为 required = false并不意味着它将注入null .当应用于构造函数时,Spring将尝试确定最适合创建实例的构造函数.在这种情况下,您只有一个需要SpellChecker的构造函数,而没有该类型的对象.

This exception happens because required = false does not mean that it will inject null. When applied to constructors Spring will try to decide which constructor is best suited for creating the instance. In this case you have only one constructor that need a SpellChecker but no object of that type.

如Spring文档中所述(

As referenced in the Spring doc (http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html):

任何给定bean类的一个构造函数(最大)都可以带有此注释,指示在用作Spring bean时可以自动装配的构造函数.这样的构造函数不必是公共的.

Only one constructor (at max) of any given bean class may carry this annotation, indicating the constructor to autowire when used as a Spring bean. Such a constructor does not have to be public.

无论如何,您都可以添加一个默认的构造函数(可以是私有的),这样当Spring无法执行其@Autowired魔术时,它将使用该构造函数.在您的TextEditor类中,您可以添加:

Anyway you can add a default constructor (it can be private) so that when Spring can't do its @Autowired magic it will use that one. In you TextEditor class you could add:

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

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

Note that @Deprecated is used to avoid your compiler to warn you that you have a private constructor that no one uses.

这篇关于构造函数上的@Autowired(required = false)给出NoSuchBeanDefinitionException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆