我们来看看ConfigurationBootstrap是如何加载ResteasyDeployment的:
ConfigurationBootstrap是Servlet容器。因为ResteasyDeployment是独立于容器的,所以不一定由ConfigurationBootstrap来加载(目前RESTEasy还支持TJWS,Netty等多种容器)。但ConfigurationBootstrap加载过程有代表性,所以我们可以用它做为参考。
ConfigurationBootstrap的入口是createDeployment():
一开始是加载ResteasyDeployment,读入配置等细节,这些在前一篇文章中有介绍。注意在最后它所加载的injector factory。对应到代码中是这样:
deployment.setInjectorFactoryClass(injectorFactoryClass);
如代码所示ConfigurationBootstrap将InjectorFactory注入ResteasyDeployment。而ResteasyDeployment又将InjectorFactory注入ResteasyProviderFactory:
providerFactory.setInjectorFactory(injectorFactory);
我们来看一下InjectorFactory:
Injector的作用就是将HTTP请求发过来的数据映射至REST方法,以及REST方法中的参数。比如下面这段代码:
@Path("/products")
public static class ProductService
{
@GET
@Produces("application/xml")
@Path("{id}")
public Product getProduct(@PathParam("id") int id)
{
Product p = new Product();
p.setId(id);
p.setName("iphone");
p.getLinks().add(new RelativeLink("self", "/self"));
p.getLinks().add(new BaseLink("create", "/products"));
return p;
}
}
Injector的作用就是把HTTP请求"/products/{id}"映射至getProduct方法,再把id的值映射到int id这个parameter上面。
可以看到InjectorFactory中包含很多种Injector,以下是它们之间的关系:
我们可以看到在各种Injector中,并列的三个是ConstructorInjector,MethodInjector及PropertyInjector。从名字就可以看出,它们是把HTTP请求映射至Java类的Constructor,方法以及方法的参数。
上面三个Injector大类中,包含各中ValueInjector。这些ValueInjector就是用来映射具体的请求数据的:
这些Injector会负责进行具体的http请求<->java数据类型的具体转换。可以看到这些Injector对应那些@*Param标记。比如:
@GET
public Object foo(@QueryParam("bar") int bar) {
...
}
那么http请求中bar对应的数据就由QueryParamInjector进行解析并注入int bar。