Ratpack as I wrote before By registering various parts in the Registry
class, a modular architecture is realized. It's ideal and flexible in itself, but I think large-scale development will still require a full-fledged DI container. Ratpack can use the DI function of Google Guice or Spring as Registry
.
Guice
You can create a Registry
from the ratpack.guice.Guice
class. Please note that the name is com.google.inject.Guice
. This is an example of creating a Registry
from the ʻInjector` class.
Injector injector = Guice.createInjector( new CustomModule() );
Registry registry = ratpack.guice.Guice.registry( injector );
You can also create modules only from the API inside Ratpack. The type is Function <Registry, Registry>
, but you can pass it directly to RatpackServerSpec.registry ()
.
Function<Registry, Registry> registry = ratpack.guice.Guice.registry( bindings -> {
bindings.module( CustomModule.class );
} );
It should be noted that the addition of modules is affected in order. The contents will be overwritten in the module added later.
Usage is the same as normal Registry
. You can get the class registered in the Guice injector from the Registry
API. If you specify a handler etc. by class name, it will be fetched from the container. Instances are managed by Guice, so you can specify dependencies with @ Inject
just like you would with regular Guice code.
public final class CustomHandler implements Handler {
private Database database;
@Inject
public CustomHandler( Database database ) {
this.database = database;
}
@Override
public void handle( Context ctx ) throws Exception {
ctx.render( "CustomHandler: " + database.find() );
}
}
Action<Chain> handlers = chain -> {
chain.all( CustomHandler.class );
};
InjectionHandler
Ratpack provides the ʻInjectionHandler` class to reduce Guice's boilerplate.
public static final class CustomInjectionHandler extends InjectionHandler {
public void handle( Context context, Database database ) {
context.render( "CustomInjectionHandler: " + database.find() );
}
}
The class that inherits ʻInjectionHandler implements only one function with the name
handlerand
Contextas the first argument. After
Context`, describe the dependency you want to inject as an argument.
Internally, it takes the form of delegating processing to the method by reflection in response to the handler call.
Considering performance and IDE support, I personally prefer not to use it much.
Spring
You can create a Registry
from a Spring DI container with theratpack.spring.Spring.spring ()
method.
Registry registry = Spring.spring( Application.class );
The class specified in the argument is the class with the @SpringBootApplication
annotation. Just like you would use it in a regular Spring application, the components are searched in the classpath and those classes can be retrieved from Registry
.
@Service
public class CustomRenderer implements Handler {
private final CustomRepository repository;
@Autowired
public CustomRenderer( CustomRepository repository ) {
this.repository = repository;
}
@Override
public void handle( Context ctx ) throws Exception {
ctx.render( "Hello from Spring Boot!" );
}
}
@Repository
public static class CustomRepository {
public String find() {
return "This is the mock database.";
}
}
Action<Chain> handlers = chain -> {
chain.all( CustomRenderer.class );
};
I think the use of DI containers is almost mandatory in the Java ecosystem. Ratpack provides support for two of the most popular DI containers, Guice and Spring. Guice is also used to integrate each of Ratpack's extension modules.
Ratpack and Guice are tightly integrated, and DI itself is a powerful way to loosely couple applications. We recommend that you use it positively.
Recommended Posts