Using with Spring and Injection frameworks
The Juneau REST server API is compatible with dependency injection frameworks such as Spring.
The important class is the {@link oajr.RestResourceResolver} class which is used
to resolve child servlet/resource implementation classes inside parent contexts.
In other words, it's used for resolving {@link oajr.annotation.Rest#children() @Rest(children)} instances.
The general approach starts with defining a resolver that uses the Spring application context for resolution:
public class SpringRestResourceResolver extends RestResourceResolverSimple {
private final ApplicationContext appContext;
public SpringRestResourceResolver(ApplicationContext appContext) {
this.appContext = appContext;
}
@Override /* RestResourceResolverSimple */
public Object resolve(Class<?> resourceType, RestContextBuilder builder) throws Exception {
Object resource = appContext.getBean(type);
// If Spring can't resolve it, use default resolution (just look for no-arg constructor).
if (resource == null) {
resource = super.resolve(resourceType, builder);
}
return resource;
}
}
Next, define the Spring configuration to return our resolver:
@Configuration
public abstract class MySpringConfiguration {
@Autowired
private static ApplicationContext appContext;
public static ApplicationContext getAppContext(){
return appContext;
}
public static void setAppContext(ApplicationContext appContext){
MySpringConfiguration.appContext = appContext;
}
@Bean
public RestResourceResolver restResourceResolver(ApplicationContext appContext) {
return new SpringRestResourceResolver(appContext);
}
}
Finally, define your Root resource with a constructor that takes in our rest resource resolver and
sets it on the config object during initialization.
@Rest(
children={
...
}
)
public class Root extends BasicRestServletGroup {
private final RestResourceResolver resolver;
@Inject
public Root(RestResourceResolver resolver) {
this.resolver = resolver;
}
@RestHook(INIT)
public void initSpring(RestContextBuilder builder) throws Exception {
builder.setResourceResolver(resolver);
}
}
After that, just define constructors on your child resources to take in Spring beans:
@Rest(
path="/child"
)
public class MyChildResource extends BasicRestServlet {
private final Bean1 bean1;
private final Bean2 bean2;
private final Bean3 bean3;
@Inject
public MyChildResource(Bean1 bean1, Bean2 bean2, Bean3 bean3) {
this.bean1 = bean1;
this.bean2 = bean2;
this.bean3 = bean3;
}