All Downloads are FREE. Search and download functionalities are using the official Maven repository.

templates.docs.bootstrapping.html Maven / Gradle / Ivy

There is a newer version: 2.2.0
Show newest version
{#==========================================
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.





© 2015 - 2024 Weber Informatics LLC | Privacy Policy