[英]Access HttpServletRequest using @Context annotaion in business layer
我可以在我的rest服務中使用@Context注釋來訪問HttpServletRequest。 但是無法訪問存儲庫類中的相同對象。我不想在調用方法時將請求形式MyService傳遞給MyRespository。
@Path("/someUrl")
public MyService{
@Context
private HttpServletRequest request;
@Get
public void someMethod()
{
myRepository.someMethod();
}
}
但是相同的注釋不適用於我的存儲庫類
@Repository
public MyRepository
{
@Context
private HttpServletRequest request;
public void someMethod()
{
//need request here
}
}
它注入空請求。 不知道為什么這不起作用。
問題在於Jersey( 及其 DI框架HK2)的集成方式是可以將Spring組件注入到Jersey(HK2)組件中,反之亦然。 HttpServletRequest
被綁定為Jersey組件。
您可以做的是創建一個HK2服務,該服務包裝Spring回購和HttpServletRequest
。 IMO,無論如何,這是更好的設計。 存儲庫不應與HttpServletRequest
,而僅與數據有關。
所以你可以有
public class MyService {
@Inject // or @Autowired (both work)
private MyRepository repository;
@Context
private HttpServletRequest request;
}
然后將服務與HK2綁定
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.process.internal.RequestScoped;
public class AppBinder extends AbstractBinder {
@Override
public void configure() {
bindAsContract(MyService.class).in(RequestScoped.class);
// note, if `MyService` is an interface, and you have
// an implementation, you should use the syntax
//
// bind(MyServiceImpl.class).to(MyService.class).in(...);
//
// Then you inject `MyService`. Whatever the `to(..)` is,
// that is what you can inject
}
}
並在澤西島注冊活頁夾
public class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
register(new AppBinder());
}
}
然后,您可以將MyService
注入資源類。
如果您不想走這條路,則需要將MyRepository
為HK2服務,或使用HK2 Factory
打包存儲庫並顯式注入它。 就像是
import javax.inject.Inject;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.api.ServiceLocator;
import org.springframework.context.ApplicationContext;
public class MyRepositoryFactory implements Factory<MyRepository> {
private final MyRepository repo;
@Inject
public MyRepositoryFactory(ApplicationContext ctx, ServiceLocator locator) {
MyRepository r = ctx.getBean(MyRepository.class);
locator.inject(r);
this.repo = r;
}
@Override
public MyRepository provide() {
return repo;
}
@Override
public void dispose(MyRepository t) {/* noop */}
}
然后注冊工廠
@Override
public void configure() {
bindFactory(MyRepositoryFactory.class).to(MyRepository.class).in(Singleton.class);
}
如果執行上述操作,則只需使用MyRepository
,而不添加服務層。 基本上,您需要從Spring獲取存儲庫,並顯式地將其注入HK2 ServiceLocator
(它是Spring ApplicationContext
的HK2類似物)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.