为什么我需要在控制器中使用spring注释?

时间:2016-01-07 11:03:47

标签: java spring spring-mvc playframework

我是新手,也是春天。开始在项目中工作,如果我只是创建我的控制器类:

package controllers;

import play.mvc.Controller;
import play.mvc.Result;

public class Users extends Controller {

    public Result login(){
        return ok(views.html.login.render());
    }

}

我遇到了这个例外:

[NoSuchBeanDefinitionException: No qualifying bean of type [controllers.Users] is defined]

enter image description here

但是,如果我在春季从顶层插入这个传单:

package controllers;

import play.mvc.Controller;
import play.mvc.Result;

@org.springframework.stereotype.Controller
public class Users extends Controller {

    public Result login(){
        return ok(views.html.login.render());
    }

}

页面已呈现。但我不知道为什么会这样。我想在必要的时候使用弹簧,充分发挥其作用。所以我想知道我在控制器上使用这个注释是否正确。

修改

import configuration.WebAppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import play.Application;
import play.GlobalSettings;

/**
 * Application wide behaviour. We establish a Spring application context for the dependency injection system and
 * configure Spring Data.
 */
public class Global extends GlobalSettings {

    /**
     * The name of the persistence unit we will be using.
     */
    static final String DEFAULT_PERSISTENCE_UNIT = "default";

    /**
     * Declare the application context to be used - a Java annotation based application context requiring no XML.
     */
    final private AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();

    /**
     * Sync the context lifecycle with Play's.
     */
    @Override
    public void onStart(final Application app) {
        super.onStart(app);

        // AnnotationConfigApplicationContext can only be refreshed once, but we do it here even though this method
        // can be called multiple times. The reason for doing during startup is so that the Play configuration is
        // entirely available to this application context.
        ctx.register(SpringDataJpaConfiguration.class);
        ctx.scan("controllers", "models");
        ctx.refresh();

        // This will construct the beans and call any construction lifecycle methods e.g. @PostConstruct
        ctx.start();

    }

    /**
     * Sync the context lifecycle with Play's.
     */
    @Override
    public void onStop(final Application app) {
        // This will call any destruction lifecycle methods and then release the beans e.g. @PreDestroy
        ctx.close();

        super.onStop(app);
    }

    /**
     * Controllers must be resolved through the application context. There is a special method of GlobalSettings that we
     * can override to resolve a given controller. This resolution is required by the Play router.
     */
    @Override
    public <A> A getControllerInstance(Class<A> aClass) {
        return ctx.getBean(aClass);
    }

    /**
     * This configuration establishes the Spring context which in our case is defined in the "other" project.
     */
    @Configuration
    @Import(WebAppConfig.class)
    public static class SpringDataJpaConfiguration {
        // At the moment this class is just a entry point for the "other project" Spring context config, AppContext
    }

}

编辑2: 伙计们,现在我记得在这个项目中有一些东西,我们有2个项目,一个完全在javaspring开发,这个是webapp。我们正在使用play从这个项目的第一个项目中导入.jar。我们这样做,所以我们不必维护两种不同的模型。

3 个答案:

答案 0 :(得分:2)

在您的班级Global中,您实际上告诉Playframework从Spring应用程序上下文中解析控制器:

@Override
public <A> A getControllerInstance(Class<A> aClass) {
    return ctx.getBean(aClass);
}

在这种情况下很明显,您必须在控制器上安装Spring注释,否则它们将不会添加到应用程序上下文中。如果您不想从应用程序上下文中解析控制器,请删除该方法。但请记住,您将无法在Play控制器中注入Spring组件,因为它们不是由Spring管理的。

答案 1 :(得分:1)

您熟悉IoC(控制反转)和DI(依赖注入)吗? Spring IoC has a container它需要了解每个组件。您必须使用配置文件/配置类对其进行配置,并且注释可以用于避免进行大量配置。

答案 2 :(得分:1)

如果你想从Spring的bean must be managed by Spring上下文中检索一个bean实例。将@Controller添加到控制器并启用指向其包(或超级包)的组件扫描会告诉Spring在其上下文中创建该类的实例,这是您最近可以使用的实例。

拥有说,here解释了为什么你有这个例外。