将bean自动装入我的控制器。防止使用getBean方法

时间:2016-10-09 08:12:59

标签: spring maven autowired

我正在尝试一个小型应用程序,对Spring mvc框架来说还是一个新手。我有一个控制器类和一个bean配置xml文件。如果我调用getBean()方法,我可以使用bean。但是我的计划是使用自动装配将bean注入我的控制器而不是使用getBean()。但我得到错误。我正在使用maven来构建我的项目。这是我在src / main / java

下的包中的Controller类
package com.eat.menu.controller;

import java.util.Date;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.eat.admin.config.Globals.DishCategory;
import com.eat.admin.config.Globals.MenuStatus;
import com.eat.menu.model.Dish;
import com.eat.menu.model.Menu;

@Controller
public class MenuController {


private static int counter = 0;
    private static final String VIEW_INDEX = "index";
    private final static org.slf4j.Logger logger =

LoggerFactory.getLogger(MenuController.class);

    @Autowired
    private MongoTemplate mongoTemplate;

    public MongoTemplate getMongoTemplate() {
        return mongoTemplate;
    }

    public void setMongoTemplate(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
    }

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String welcome(ModelMap model) {

        model.addAttribute("message", "Welcome");
        model.addAttribute("counter", ++counter);
        logger.debug("[welcome] counter : {}", counter);

        // Spring uses InternalResourceViewResolver and return back index.jsp
        return VIEW_INDEX;

    }

    @RequestMapping(value = "/{name}", method = RequestMethod.GET)
    public String welcomeName(@PathVariable String name, ModelMap model) {

        model.addAttribute("message", "Welcome " + name);
        model.addAttribute("counter", ++counter);
        logger.debug("[welcomeName] counter : {}", counter);
        return VIEW_INDEX;

    }

    @RequestMapping(value = "/menu", method = RequestMethod.GET)
    public String createMenu(ModelMap model) {
        ApplicationContext ctx = new GenericXmlApplicationContext("BaseConfig.xml");
//Avoid using this
        MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");

        Dish dish1 = new Dish();
        Date now = new Date();
        dish1.setName("Butter Chicken");
        dish1.setCategory(DishCategory.ENTREE);
        dish1.setCreateDate(now);
        dish1.setUpdateDate(now);

        Dish dish2 = new Dish();
        dish2.setName("Korma Chicken");
        dish2.setCategory(DishCategory.ENTREE);
        dish2.setCreateDate(now);
        dish2.setUpdateDate(now);

        Dish [] dishes = new Dish[2];
        dishes[0] = dish1;
        dishes[1] = dish2;

        Menu menu = new Menu();
        menu.setCompanyId(1);
        menu.setCreateDate(now);
        menu.setUpdateDate(now);
        menu.setDishes(dishes);
        menu.setMenuStatus(MenuStatus.ACTIVE);

        mongoOperation.save(menu);

        Query searchMenuQuery = new Query(Criteria.where("companyId").is(1));

        // find the saved user again.
        Menu m = mongoOperation.findOne(searchMenuQuery, Menu.class);
        return VIEW_INDEX;
    }
}

这是我在src / main / resources

下的baseConfig.xml
<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"
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/data/mongo
      http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd">

<context:annotation-config/>

<mongo:mongo host="127.0.0.1" port="27017" />
<mongo:db-factory dbname="eatMongoDB" />

<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>

<bean id="menuController" class="com.eat.menu.controller.MenuController">
    <property name="mongoTemplate" value="mongoTemplate"/>
</bean>

如果我做错了,请告诉我,因为我收到以下错误:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'menuController': Unsatisfied dependency expressed through field 'mongoTemplate': No qualifying bean of type [org.springframework.data.mongodb.core.MongoTemplate] found for dependency [org.springframework.data.mongodb.core.MongoTemplate]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.mongodb.core.MongoTemplate] found for dependency [org.springframework.data.mongodb.core.MongoTemplate]: 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:569)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:349)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:776)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:444)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:326)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4715)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5177)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:152)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1403)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1393)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.mongodb.core.MongoTemplate] found for dependency [org.springframework.data.mongodb.core.MongoTemplate]: 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.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1406)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1057)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1019)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:566)
    ... 24 more

为了清楚起见,我添加了3个配置文件,让我知道是否需要任何内容​​:第一个是pom文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation =“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”&gt;     4.0.0     com.eat     EatApp     战争     1.0-SNAPSHOT     EatApp Maven Webapp     http://maven.apache.org

<properties>
    <jdk.version>1.8</jdk.version>
    <spring.version>4.3.2.RELEASE</spring.version>
    <jstl.version>1.2</jstl.version>
    <junit.version>4.12</junit.version>
    <logback.version>1.1.7</logback.version>
    <jcl-over-slf4j.version>1.7.21</jcl-over-slf4j.version>
</properties>

 <dependencies>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${jcl-over-slf4j.version}</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <!-- Spring Framework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Mongo dependencies -->
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.3.0</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>1.9.2.RELEASE</version>
    </dependency>

    <!-- jstl -->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>${jstl.version}</version>
    </dependency>

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.4</version>
    </dependency>

 </dependencies>

 <build>
    <finalName>EatApp</finalName>

    <plugins>
        <!-- Eclipse project -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-eclipse-plugin</artifactId>
        <version>2.10</version>
        <configuration>
                <!-- Always download and attach dependencies source code -->
            <downloadSources>true</downloadSources>
            <downloadJavadocs>false</downloadJavadocs>
            <!-- Avoid type mvn eclipse:eclipse -Dwtpversion=2.0 -->
            <wtpversion>2.0</wtpversion>
        </configuration>
      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.5.1</version>
        <configuration>
            <source>${jdk.version}</source>
            <target>${jdk.version}</target>
        </configuration>
      </plugin>
      <!--  
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
            <path>/EatApp</path>
        </configuration>
      </plugin>
      -->

    </plugins>
 </build>

web.xml:

    <!--  <!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
 -->

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

  <display-name>EatApp Web Application</display-name>

  <servlet>
       <servlet-name>mvc-dispatcher</servlet-name>
       <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
       </servlet-class>
       <!--  
       <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/BaseConfig.xml
            </param-value>
        </init-param>
        -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>

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

servlet文件:mvc-dispatch-servlet:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.eat.menu.controller" />

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix">
        <value>/WEB-INF/pages/</value>
    </property>
    <property name="suffix">
        <value>.jsp</value>
    </property>
</bean>

2 个答案:

答案 0 :(得分:0)

您似乎只在contextConfigLocation参数中设置了配置文件/WEB-INF/mvc-dispatcher-servlet.xml。将baseConfig.xml的内容添加到该内容,然后重试。如果这解决了问题,那么稍后,您可以设法使用多个配置文件。

答案 1 :(得分:-1)

如果你想使用注释,必须在你的配置中定义组件扫描,你可以告诉spring哪个包需要这个自动扫描。

<context:component-scan base-package="com.xxx.xxx"/>

例外说:除了至少1个符合条件的豆子......这意味着春天无法找到它。 如果要将bean注入控制器,@Resource要比@Autowired好得多。因为

@Autowired
    按类型注入。如果要按名称注入,则必须添加@Qualifier()注释。如果使用@Autowired,则必须确保依赖bean存在。如果允许为null,请添加@Autowired(required=false)。 我发现你的例外是

No qualifying bean of type [org.springframework.data.mongodb.core.MongoTemplate] found for dependency [org.springframework.data.mongodb.core.MongoTemplate]: 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.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1406)

检查你的MongoTemplate bean,也许它甚至不存在,或者你的弹簧容器找不到它。

@Autowired()
@Qualifier("mongoTemplate")
private MongoTemplate mongoTemplate; // Autowired. Inject by type. if you want to inject by name, you must add @Qualifier() annotation.

@Resource
   按名称注入。如果你想按名称注入

@Resource(name="mongoTemplate")
private MongoTemplate mongoTemplate; // Resource. Inject by name.

最重要的是@Resource属于J2EE@Autowired属于Spring。他们俩都会解决这个问题,但是 如果你弄清楚如何,你会更好。希望这会对你有所帮助。