我是新手,也是春天。开始在项目中工作,如果我只是创建我的控制器类:
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]
但是,如果我在春季从顶层插入这个传单:
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个项目,一个完全在java
和spring
开发,这个是webapp。我们正在使用play从这个项目的第一个项目中导入.jar
。我们这样做,所以我们不必维护两种不同的模型。
答案 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解释了为什么你有这个例外。