MG_7
MG_7

Reputation: 61

@Inject and @Named annotation giving NoSuchBeanDefinitionException

I have the following Classes implementing LogWriter Interface(

all are custom classes with these names not the standard java package classes

) inside package com.springprogramming.spring.test.model

@Component
public class ConsoleWriter implements LogWriter{    

public void write(String st){
    System.out.println("in Console writer "+st);
}
}

@Component("fileWriter")
public class FileWriter implements LogWriter{   

public void write(String st){
    System.out.println("in Console writer "+st);
}
}

public interface LogWriter {

public  void write(String st);
}

@Component

public class Logger {

private ConsoleWriter consoleWriter;

private LogWriter fileWriter;


@Inject
public void setConsoleWriter(ConsoleWriter consoleWriter) {
    this.consoleWriter = consoleWriter;
}

@Inject
@Named(value="fileWriter")
public void setFileWriter(LogWriter fileWriter) {
    this.fileWriter = fileWriter;
}

public void writeFile(String text){
    fileWriter.write(text);
}


public void writeConsole(String text){
    if(consoleWriter!=null)
        consoleWriter.write(text);
}

@PostConstruct
public void init(){
    System.out.println("init");
}

@PreDestroy
public void destroy(){
    System.out.println("destroy");
}
}

I am trying to skip the bean defined in my spring config xml file(app-config.xml), thus using component scan inside my base package:

<context:annotation-config></context:annotation-config>
<context:component-scan
    base-package="com.springprogramming.spring.test.model">
</context:component-scan>

Now in my main class (App3.java)

    public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("/com/springprogramming/spring/test/beans/app-config.xml");

    Logger logger = (Logger)context.getBean("logger");
    logger.writeConsole("HI ");
    logger.writeFile("Hello");

    ((ClassPathXmlApplicationContext)context).close();

}

When I run this program , i am getting error (when I use @Named with @Inject over my setFileWriter method ,i get following exception. If I remove @Named annotation , it executes fine

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.springprogramming.spring.test.model.LogWriter] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.

What's wrong with this program? Thanks in advance.

Upvotes: 1

Views: 9145

Answers (1)

hotzst
hotzst

Reputation: 7496

I am not sure why you do not make the parameter type specific for FileWriter, as the method name already suggests this (in that case you do not need the @Named anymore):

public void setFileWriter(FileWriter fileWriter) {
    this.fileWriter = fileWriter;
}

If that is not what you want, you should place the @Named with the parameter: public void setFileWriter(@Named("fileWriter") LogWriter fileWriter) { this.fileWriter = fileWriter; } See also the documentation of Spring. This is a very unusual way to set the fileWriter, a better approach would be, to inject the FileWriter with the declaration of the field:

@Inject
@Named("fileWriter")
private LogWriter fileWriter;

I personally find it cleaner to have annotations on the fields instead of the setter methods, as in many cases you do not need an explicit setter method.

Upvotes: 1

Related Questions