2014-04-24 58 views
8

在Spring應用程序中,我在構造函數上使用了@Autowired(required=false)。這意味着如果將自動裝配的bean在xml文件中不可用,則不應引發NoSuchBeanDefinitionException,因爲(required=false)被提及。但是我得到了UnsatisfiedDependencyExceptionNoSuchBeanDefinitionException的例外。@Autowired(required = false)給構造函數賦予NoSuchBeanDefinitionException

----文本編輯

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

<?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[email protected]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.s[email protected]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.s[email protected]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)被提及以後,異常也不應該出現。

回答

8

這個異常是因爲需要= false並不意味着它會注入空。當應用於構造函數時,Spring將嘗試確定哪個構造函數最適合創建實例。在這種情況下,你只有一個構造函數需要一個SpellChecker,但沒有該類型的對象。

如春季DOC(http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html)引用:任何給定的bean類的

只有一個構造(最大)可以執行此註解,說明構造作爲一個Spring bean使用時自動裝配。這樣的構造函數不必公開。

無論如何,你可以添加一個默認構造函數(它可以是私有的),這樣當Spring不能執行它的@Autowired魔法時,它將使用該構造函數。在您文本編輯類,你可以添加:

@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用來避免你的編譯器警告你,你有沒有人使用私有構造。

+0

如果我嘗試和可選的依賴關係是不存在的春天拋出'UnsatisfiedDependencyException' –

3

我也有類似的問題。 其實,你可以有幾個構造函數與

@Autowired(required = false) 

,但付出,你不能在默認情況下添加此註釋(不帶參數)注意構造函數,因爲@Autowired註解至少需要一個參數

+0

這對我的作品,但它根據的Javadoc似乎不應該! –

相關問題