【发布时间】:2017-03-28 23:45:47
【问题描述】:
我已经使用 Spring Rest 完成了项目。现在我们有一个小型的休息项目,并计划使用 Jersey JAX-RS。我是新手,并参考 SO 和其他博客成功实现了带有依赖注入的 Rest api。
有以下代码。
AppConfig.java
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/")
public class AppConfig extends Application {
@Override
public Set<Class<?>> getClasses() {
System.out.println("AppConfig");
final Set<Class<?>> s = new HashSet<Class<?>>();
s.add(Controller.class);
s.add(AppFeature.class);
return s;
}
}
AppBinder.java
import org.glassfish.hk2.utilities.binding.AbstractBinder;
public class AppBinder extends AbstractBinder {
@Override
protected void configure() {
System.out.println("AppBinder");
bind(ReflectionService.class).to(ReflectionService.class);
}
}
AppFeature.java
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
public class AppFeature implements Feature {
@Override
public boolean configure(FeatureContext context) {
System.out.println("AppFeature");
context.register(new AppBinder());
return true;
}
}
Controller.java
@Path("/")
public class Controller {
@Inject
Service service;
public Controller(){
System.out.println("Controller created");
}
// other methods
}
Service.java
@Singleton
public class Service
public Service(){
System.out.println("Service instance created");
}
// other methods
}
我假设 Controller 和 Service 的每个实例都是在 Tomcat 8 服务器启动和依赖注入完成时创建的。但是在启动过程中,在控制台上得到了这个
INFO:注册 Jersey servlet 应用程序,名为 com.sample.auto2.AppConfig,在 servlet 映射 /* 处,带有 同名的应用程序类。
应用配置
应用配置
2016 年 11 月 15 日下午 12:22:20 org.glassfish.jersey.server.ApplicationHandler 初始化 INFO:启动 Jersey 应用程序,版本 Jersey:2.6 2014-02-18 21:52:53...
应用功能
AppBinder
2016 年 11 月 15 日下午 12:22:21 org.apache.catalina.startup.HostConfig 部署目录
每次,我们发送一个请求,在控制台中得到关注
已创建服务实例
控制器创建
我的问题
- 每当我们发送一个 http请求;它是在每个请求中创建实例还是只是 调用构造函数?
- 为什么 AppConfig 中的 System.out 会被调用两次?
- 有没有更好的方法来设置我的小项目,它没有任何数据库访问权限,只有三个 post 端点?
编辑:
根据@Harikrishnan 提供的链接,为Controller 类添加了@Singleton。现在构造函数只调用一次(在第一次请求时 - 为什么不在服务器启动期间!)。
但是为什么在每个请求上调用服务类构造函数(在将@Singleton 添加到控制器之前),即使它是单例的?其他问题也依然存在。
编辑 2:
谢谢@peeskillet。所以这些是我的结果。
-
这在第一次请求时只调用了一次构造函数
bind(ReflectionService.class).to(ReflectionService.class).in(Singleton.class); bind(Controller.class).to(Controller.class).in(Singleton.class); -
这给出了http请求的错误
bind(ReflectionService.class).to(ReflectionService.class).in(Immediate.class); java.lang.IllegalStateException: Could not find an active context for org.glassfish.hk2.api.Immediate不过没关系,因为
-
这在服务器启动时调用了构造函数,并且只调用了一次
bind(new ReflectionService()).to(ReflectionService.class); bind(new Controller()).to(Controller.class); -
由此,启动时完成注入,但 http 请求出现 404 错误。 (思想Controller是在AppBinder中配置的,那为什么在AppConfig中)
@ApplicationPath("/") public class AppConfig extends ResourceConfig { public AppConfig() { register(new AppBinder()); } } -
正如你所说,这让它运行!
@ApplicationPath("/") public class AppConfig extends ResourceConfig { public AppConfig() { register(new AppBinder()); register(Controller.class); } }
这些都是我需要的
public class AppBinder extends AbstractBinder {
@Override
protected void configure() {
bind(new ReflectionService()).to(ReflectionService.class);
bind(new Controller()).to(Controller.class);
}
}
@ApplicationPath("/")
public class AppConfig extends ResourceConfig {
public AppConfig() {
register(new AppBinder());
register(Controller.class);
}
}
【问题讨论】:
标签: java jakarta-ee dependency-injection jersey jax-rs