RESTful Web 服务教程中的自动装配

Autowiring in RESTful Web Service tutorial

我已经从 here 下载了教程 zip。它包含具有主要方法

的应用程序 class
package hello;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan;

@ComponentScan
@EnableAutoConfiguration
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

问候class

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

和 GreetingController

package hello;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping("/greeting")
    public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(),
                        String.format(template, name));
    }
}

这很好用,但是我想使用 Spring beans(使用 applicationContext.xml)创建一些 Greeting 对象,所以我创建了 src/main/resources 目录(我使用 maven 来配置本教程)并放在那里 applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean name = "greeting" class="hello.Greeting">
         <constructor-arg index="0" value = "25"  />
         <constructor-arg index="1" value = "Hello!"  />  
    </bean> 
</beans>

之后我添加

@Autowired Greeting gr;

问候控制器并获得

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'greetingController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: hello.Greeting hello.GreetingController.gr; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [hello.Greeting] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:301)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1186)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:706)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:762)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:109)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
at hello.Application.main(Application.java:12)

我怎样才能使这个建筑工作? 谢谢。

同时添加@Qualifier 注释:

@Autowired
@Qualifier("greeting")
Greeting gr;
   expected at least 1 bean which qualifies as autowire candidate for this dependency.

意味着 Spring 没有创建 Greeting class 的任何 bean,所以我猜 spring 没有导入你的文件。 Official documentaion 建议使用 @ImportResource.

所以它会是这样的:

@ComponentScan
@ImportResource("classpath:/applicationContext.xml")
@EnableAutoConfiguration
public class Application {
...
}

异常只是意味着它无法创建 bean GreetingController 因为依赖于你的 Greeting class (当你添加它并用 [=13 注释时=]).

可能是找不到您的applicationContext.xml。

确保在 web.xml

上定义这些
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
         /location/of/your/applicationContext.xml
    </param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

希望这对您有所帮助。