templates.docs.bootstrapping.html Maven / Gradle / Ivy
Show all versions of spincast-website Show documentation
{#==========================================
Docs : "bootstrapping"
==========================================#}
Bootstrapping your app
Bootstrapping a Spincast application is very easy. Most of the time,
you start with the spincast-default
Maven artifact in your
pom.xml
(or build.gradle
) :
<dependency>
<groupId>org.spincast</groupId>
<artifactId>spincast-default</artifactId>
<version>{{spincast.spincastCurrrentVersion}}</version>
</dependency>
Then, in the main(...)
method of your application,
you use the Spincast
class to initialize your application.
You can do this the "quick way", or use the Bootstrapper
to
have more options. Let see both of those approaches...
Quick initialization
The quickest way to initialize a Spincast application is to call Spincast.init(args)
:
public class App {
public static void main(String[] args) {
Spincast.init(args);
}
// ...
}
This will create a Guice context using all the default plugins,
will bind the current App
class itself in that context (as a singleton) and will load the
App
instance. You then simply
have to add an init method to your App
class to
define Routes, add some logic, and start the HTTP Server :
public class App {
public static void main(String[] args) {
Spincast.init(args);
}
@Inject
protected void init(DefaultRouter router, Server server) {
router.GET("/").handle(context -> context.response().sendHtml("<h1>Hello World!</h1>"));
server.start();
}
}
This is a simple, but totally functional Spincast application!
There is a demo page for this very example.
On that page, you can download the sources and run the application by yourself.
Finally, note that Spincast.init(args)
in fact creates a default Bootstrapper
under the hood. We will now see how you can configure this bootstrapper explicitly to have more control
over your application initialization...
The Bootstrapper
In most cases, you need more control than simply calling Spincast.init(args)
.
You want to be able to add custom modules to the Guice context, to add extra plugins, etc.
You do so by using Spincast.configure()
instead of
Spincast.init(args)
. This starts a bootstrapper to help
configure your application before it is started. Let's see an example :
public static void main(String[] args) {
Spincast.configure()
.module(new AppModule())
.plugin(new SpincastHttpClientPlugin())
.requestContextImplementationClass(AppRequestContextDefault.class)
.init(args);
//....
}
Explanation :
-
3 : We start the bootstrapper by calling
.configure()
instead of .init(args)
!
-
4 : We add a custom Guice module so
we can bind our application components.
-
5 : We add an extra plugin.
-
6 : We tell Spincast that we are using a
custom Request Context type.
-
7 : We finally call
.init(args)
so the Guice
context is created, the current class is bound and then loaded. We also use this method to bind
the arguments received in the main(...)
method to the Guice context.
Bootstapper's options :
Let's now see the bootstrapper's options (Note that none of them is mandatory,
except requestContextImplementationClass(...)
if you are using a
custom Request Context type and websocketContextImplementationClass(...)
if you are using a
custom WebSocket Context type).
-
module(...)
: Adds a Guice module.
It can be called multiple time to add more than one module. All the modules
added using this method are going to be combined together.
-
plugin(...)
: To register a plugin.
You can add multiple plugins (in addition to the default ones). They will
be applied in the order they are added to the bootstrapper.
-
disableAllDefaultPlugins()
: Disables all
the default plugins, including the core
one. If you think about
using this method, you should probably start
with the spincast-core artifact
instead of spincast-default
.
-
disableDefaultXXXXXXXPlugin()
: Disables
a default plugin. There is a version of this method for every
default plugin. If you disable a default plugin, you are responsible for
binding the required components the plugin was in charge of!
-
requestContextImplementationClass(...)
: Tells Spincast
that you are using a custom Request Context type.
You need to pass as a parameter the implementation class of your
custom Request Context type. Calling this method is mandatory if you are using
a custom Request Context type!
-
websocketContextImplementationClass(...)
: Tells Spincast
that you are using a custom WebSocket Context type.
You need to pass as a parameter the implementation class of your
custom WebSocket Context type. Calling this method is mandatory if you are using
a custom WebSocket Context type!
-
bindCurrentClass(...)
: By default,
the class in which the bootstrapper is created is automatically
bound in the Guice context (as a singleton) and its instance is loaded
when the context is ready. To disable this, you can call bindCurrentClass(false)
.
-
appClass(...)
: You can specify which class should be automatically
bound and loaded when the Guice context is ready. Calling this method will disable the
binding of the current class (as calling bindCurrentClass(false)
would do).
-
getDefaultModule(...)
: Allows you to get the Guice module
resulting from all the default plugin. You can use this (in association with
disableAllDefaultPlugins()
and module(...)
) to tweak the
Guice module generated by the default plugins.
Various bootstrapping tips
-
Have a look at the code of the Quick Start application to
see how it is bootstrapped. Also read the advanced version of the
Hello world! tutorial.
-
The bootstrapping process is all about creating a regular Guice context, so make sure
you read the Guice documentation
if you didn't already!
-
Be creative! For example, you could make the
App
class
extend SpincastConfigDefault
so you can override some default configurations right in that class!
Everything in Spincast is based on dependency injection so you can
easily replace/extend pretty much anything you want.
-
Split your application in controllers, services, repositories and utilities
and inject the components you need using the standard
@Inject
annotation. Don't put everything in the App
class, except if
your application is very small.
-
Don't forget to register your implementation classes if you
are using a custom Request Context type or a
custom Websocket Context. You do this using
the requestContextImplementationClass(...)
method and the websocketContextImplementationClass(...)
method on the Bootstrapper.
-
Remember that by using the Quick Start application as a template,
pretty much everything discussed here has already been implemented for you!
Simply load the code in your favorite IDE, and start adjusting it to meet the needs of your
application.
{#==========================================
Section "bootstrapping / boot_with_core"
==========================================#}
Using spincast-core
directly
This is an advanced topic that most applications will never need.
If you need total control over how your application is built, you
can decide to start without the default plugins
and pick, one by one, which one to add.
By using "spincast-default"
you add the default plugins as
Maven artifact but also a lot of
transitive dependencies. For example, dependencies for some
Jackson artifacts
are added by the default
Spincast Jackson Json plugin. Those
dependencies may conflict with other dependencies you use in your application.
This is a situation where you may want to start without the default plugins.
To start a Spincast application from scratch, start with the "spincast-core"
Maven artifact instead
of "spincast-default"
:
<dependency>
<groupId>org.spincast</groupId>
<artifactId>spincast-core</artifactId>
<version>{{spincast.spincastCurrrentVersion}}</version>
</dependency>
Doing so, you start with the core
code but you need to provide an implementation
for all the required components, by yourself. You generaly provide those
implementations by choosing and installing
some plugins by yourself.
For example, to provide an implementation for the
Server
and for the TemplatingEngine
components, you could use:
<dependency>
<groupId>org.spincast</groupId>
<artifactId>spincast-plugins-undertow</artifactId>
<version>{{spincast.spincastCurrrentVersion}}</version>
</dependency>
<dependency>
<groupId>org.spincast</groupId>
<artifactId>spincast-plugins-pebble</artifactId>
<version>{{spincast.spincastCurrrentVersion}}</version>
</dependency>
// ...
Note that by starting without spincast-default
, you don't
have access to the Bootstrapper!
You'll have to create the Guice context by yourself, using the modules provided by the
different plugins.
If you fail to provide an implementation for a component that would be bound by
a default plugin, you will get this kind of error when trying to start your application :
> ERROR - No implementation for org.spincast.server.Server was bound.