Spring Bean注解无需XML配置

4

我正在尽力少用XML。我已经编写了一个非常简单的程序,但它却无法正常工作。希望有人能帮我解决问题。

public class App {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext ctx = new    
AnnotationConfigApplicationContext(Logger.class);

        Logger logger = ctx.getBean(Logger.class);

        logger.writeConsole("Hello there");
        logger.writeFile("Hi again");

        ctx.close();
    }

}

接口

public interface LogWriter {
    public void write(String text);
}

文件写入器

public class FileWriter implements LogWriter {

    public void write(String text) {

    System.out.println("FileWriter: " + text);

   }

}

控制台编写器

 public class ConsoleWriter implements LogWriter{

      public void write(String text) {
      System.out.println("Console Writer: "+text);

   }

}

日志记录器

public class Logger {

@Autowired
private ConsoleWriter consoleWriter;
@Autowired
private FileWriter fileWriter;

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

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


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

public void writeConsole(String text) {
    consoleWriter.write(text);
}

@Bean
public Logger getLogger(){
    return new Logger();
    }

}

错误
Jul 02, 2015 2:52:49 PM org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@246b179d: startup date [Thu Jul 02 14:52:49 CEST 2015]; root of context hierarchy
Exception in thread "main" java.lang.NoSuchMethodError: org.springframework.core.GenericTypeResolver.resolveReturnTypeForGenericMethod(Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Class;
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:650)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:575)
    at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1344)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:356)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:327)
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:644)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:73)
    at com.main.application.App.main(App.java:10)

这是我的XML文件,但我正在尝试摆脱使用XML,只使用注释,因此我制作了这个易于理解的程序作为练习。

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


    <context:annotation-config></context:annotation-config>

</beans>

@TilmanHausherr 我的目标是不使用XML。我知道有一种方法可以做到这一点。我只是认为我的问题会帮助其他试图做同样事情的人。我是否错误地认为我必须使用XML?我以前使用过JHipster,它只有一个裸骨的XML文件。它全部都是POJO和注释。 - Mike3355
也许这个可以帮到你? https://dev59.com/qoPba4cB1Zd3GeqPwb1J - Tilman Hausherr
你的 Logger 应该有 @Configuration,否则它将不会被用作配置类。接下来,你应该将你的配置与应用程序代码分开(单一职责)。从堆栈跟踪来看,你的 jar 文件混合了(来自框架不同版本的 jars)。 - M. Deinum
2个回答

5
这个可以不需要任何xml配置。
public class App {

 public static void main(String[] args) {

  ApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

  Logger logger = ctx.getBean(Logger.class);
  logger.writeConsole("Hello there");
  logger.writeFile("Hi again");
 }
}

配置类

@Configuration
@ComponentScan
public class Config {
}

控制台写入器

@Component
public class ConsoleWriter implements LogWriter{

  public void write(String text) {
      System.out.println("Console Writer: "+text);

  }
}

FileWriter

@Component
public class FileWriter implements LogWriter {
   public void write(String text) {
      System.out.println("FileWriter: " + text);
   }
}

日志记录器

@Component
public class Logger {

@Autowired
private ConsoleWriter consoleWriter;
@Autowired
private FileWriter fileWriter;

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

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


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

public void writeConsole(String text) {
    consoleWriter.write(text);
}

}

Interface LogWriter

public interface LogWriter {

  public void write(String text);

}

Perez,我仍然遇到了**org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.beans.ConsoleWriter] found for dependency:**的问题。 - Mike3355
所有的类都在与 Config.class 相同的包中吗?如果不是,您需要修改 @ComponentScan("类所在的包")。 - Ricardo

4
假设您正在使用Spring 3.2。您的App.java应该如下所示:
@Configuration
@ComponentScan
public class App {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext ctx = new    
            AnnotationConfigApplicationContext(App.class);

    Logger logger = ctx.getBean(Logger.class);

    logger.writeConsole("Hello there");
    logger.writeFile("Hi again");

    ctx.close();
  }

}

@Configuration:告诉Spring此类为配置类。
@ComponentScan:告诉Spring扫描该包中的所有类。
从这个起点开始,不再需要使用xml。
FileWriter、ConsoleWriter和Logger是组件。当您定义组件时,可以在这些类上使用@Autowired注释。您需要添加@Component注释在这些类上。
请注意,@Bean getLogger()方法将在运行时引发异常,因为Spring会找到两个名称为“logger”的定义。因此,为了使应用程序正确运行,您需要删除该方法。

我按照您说的做了一切,但是我收到了一个“找不到类型为[com.beans.ConsoleWriter]的合格bean依赖项”的错误提示。为了确保没有缓存问题,我也清理了项目。 - Mike3355
@Componentscan 在一个包名为 com.app 的类中将会扫描 com.app.** 下的内容。因此,如果 App.java 在其它分支的包中,则无法找到您的 Bean。请使用 @ComponentScan({"com.beans","com.app"})。 - bodyjares

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接