Java 使用Jersey 2.0,如何为每个请求注册一个可绑定实例?
…如果实例需要手动构造,可能是由第三方工厂类构造?之前,(Jersey 1.x),您会这样做:Java 使用Jersey 2.0,如何为每个请求注册一个可绑定实例?,java,dependency-injection,jersey,jersey-2.0,Java,Dependency Injection,Jersey,Jersey 2.0,…如果实例需要手动构造,可能是由第三方工厂类构造?之前,(Jersey 1.x),您会这样做: public class MyInjectableProvider extends PerRequestTypeInjectableProvider<Context, MyInjectable> { public MyInjectableProvider() { super(MyInjectable.class); } @Override
public class MyInjectableProvider extends PerRequestTypeInjectableProvider<Context, MyInjectable> {
public MyInjectableProvider() {
super(MyInjectable.class);
}
@Override
public Injectable<MyInjectable> getInjectable(ComponentContext ic, Context context) {
MyInjectable myInjectableInstance = //...
return new Injectable<MyInjectable>() {
@Override
public MyInjectable getValue() {
return myInjectableInstance;
}
};
}
}
这“似乎有效”,但也似乎有点不清楚。例如,从不调用dispose()。此外,该绑定似乎隐式地表现为RequestScope。将配置修改为bindFactory(this).to(MyInjectable.class).in(RequestScoped.class)代码>似乎没有实际更改行为。我是否遗漏了什么,或者这是预期的解决方案?代替了工厂。dispose(T)
,向injectableCloseableService注册可以实现您想要的大部分功能。需要一个CloseableFactory
适配器CloseableService
closes()
退出请求范围时所有注册的资源
有关特定示例,请参见下面的连接工厂
import org.glassfish.hk2.api.Factory;
import org.glassfish.jersey.server.CloseableService;
import javax.inject.Inject;
import javax.ws.rs.InternalServerErrorException;
import java.sql.Connection;
import java.sql.SQLException;
import static com.google.common.base.Preconditions.checkNotNull;
public class ConnectionFactory implements Factory<Connection> {
private final CloseableService closeableService;
@Inject
public ConnectionFactory(CloseableService closeableService) {
this.closeableService = checkNotNull(closeableService);
}
public Connection provide() {
final Connection connection;
try {
connection = acquireConnection();
} catch (SQLException e) {
throw new InternalServerErrorException(e);
}
try {
closeableService.add(new CloseableConnection(connection));
} catch (Throwable t) {
closeQuietly(connection);
throw runtime(t);
}
return connection;
}
public void dispose(Connection connection) {
closeQuietly(connection);
}
private static RuntimeException runtime(Throwable t) {
throw ConnectionFactory.<RuntimeException>unchecked(t);
}
private static <T extends Throwable> T unchecked(Throwable t) throws T {
throw (T) t;
}
private static void closeQuietly(Connection connection) {
try {
connection.close();
} catch (SQLException ignore) {}
}
}
我也面临着同样的问题。你的“编辑”很有帮助。非常感谢。在阅读你文章的最后一段之前,我也发现,dispose
从来不会在请求后调用。你找到原因了吗?你好,你在项目中使用的是哪个DI框架?因为我可以提供几个例子,说明我们如何使用guice和weld进行工作。对于guice,使用guice persist,其中EntityManager是请求的作用域。使用Weld,我们提供了请求范围。我们将存储库注入JAX资源。每个存储库,注入EM,用于解决数据库操作。默认范围是请求范围。当然,明确声明这一点并不会改变这一点。例如,您可以使用singleton.class
将其声明为singleton作用域,或者您不喜欢此解决方案的什么?是否希望工厂返回的RequestScoped
值不会传递到同一工厂dispose
方法?@PavelBucek问题在于。
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(new MyInjectableProvider());
}
}
import org.glassfish.hk2.api.Factory;
import org.glassfish.jersey.server.CloseableService;
import javax.inject.Inject;
import javax.ws.rs.InternalServerErrorException;
import java.sql.Connection;
import java.sql.SQLException;
import static com.google.common.base.Preconditions.checkNotNull;
public class ConnectionFactory implements Factory<Connection> {
private final CloseableService closeableService;
@Inject
public ConnectionFactory(CloseableService closeableService) {
this.closeableService = checkNotNull(closeableService);
}
public Connection provide() {
final Connection connection;
try {
connection = acquireConnection();
} catch (SQLException e) {
throw new InternalServerErrorException(e);
}
try {
closeableService.add(new CloseableConnection(connection));
} catch (Throwable t) {
closeQuietly(connection);
throw runtime(t);
}
return connection;
}
public void dispose(Connection connection) {
closeQuietly(connection);
}
private static RuntimeException runtime(Throwable t) {
throw ConnectionFactory.<RuntimeException>unchecked(t);
}
private static <T extends Throwable> T unchecked(Throwable t) throws T {
throw (T) t;
}
private static void closeQuietly(Connection connection) {
try {
connection.close();
} catch (SQLException ignore) {}
}
}
import java.io.Closeable;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import static com.google.common.base.Preconditions.checkNotNull;
public final class CloseableConnection implements Closeable {
private final Connection connection;
public CloseableConnection(Connection connection) {
this.connection = checkNotNull(connection);
}
public void close() throws IOException {
try {
connection.close();
} catch (SQLException e) {
throw new IOException(e);
}
}
}