2014-04-24 14 views
8

In un'applicazione Spring, ho utilizzato @Autowired(required=false) sul costruttore. Ciò significa che se il bean che verrà eseguito automaticamente non è disponibile nel file xml, non è necessario inserire NoSuchBeanDefinitionException come (required=false). Ma sto ricevendo l'eccezione UnsatisfiedDependencyException, NoSuchBeanDefinitionException.@Autowired (richiesto = falso) sul costruttore che fornisce NoSuchBeanDefinitionException

---- 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(); 
    } 
} 

---- SpellChecker

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()); 
    } 
} 

--- Console (risultato effettivo)

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 

--- Risultato previsto Il programma deve essere eseguito senza alcun Exception come @Autowire(required=false) è menzionato per il costruttore. Anche se il bean non viene trovato, l'eccezione non dovrebbe venire dal momento che (required=false) è menzionata.

risposta

8

Questa eccezione si verifica perché obbligatorio = falso non significa che verrà iniettato Null. Quando viene applicato ai costruttori, Spring tenterà di decidere quale costruttore è più adatto per creare l'istanza. In questo caso hai un solo costruttore che ha bisogno di un SpellChecker ma nessun oggetto di quel tipo.

Come riferimento nel Spring doc (http://docs.spring.io/spring/docs/4.0.x/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html):

Solo un costruttore (max) di una determinata classe bean può effettuare questa annotazione, indicando il costruttore di autowire quando usato come fagiolo primaverile. Un tale costruttore non deve essere pubblico.

In ogni caso è possibile aggiungere un costruttore di default (che può essere privato) in modo che quando la primavera non può fare la sua magia @Autowired userà quello. In te TextEditor classe che si potrebbe aggiungere:

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

Nota che @deprecated viene utilizzato per evitare il compilatore per avvertire che si dispone di un costruttore privato che nessuno usa.

+0

Se io provalo e la dipendenza opzionale non è presente Spring lancia 'UnsatisfiedDependencyException' –

3

Ho avuto un problema simile. In realtà, è possibile avere diversi costruttori con

@Autowired(required = false) 

ma, attenzione che non è possibile aggiungere questa annotazione sul default (senza argomenti) costruttore, perché @Autowired annotazione richiede almeno un argomento

+0

Questo funziona per me ma sembra che secondo Javadocs non dovrebbe! –

Problemi correlati