Spring Boot + Maven = Anna valaistunutta kenkää!

Oh dear, mahtaako tuo sanaleikki aueta kenellekään? Ainakin syytä tarkistaa wikipedia 😉

Kaksi lempivimpaintani, Spring ja Maven, ovat monessa projektissa pohjana. Spring on menossa suuntaan jossa pyritään helpottamaan sen aloitusta ja projekti on nimeltään Spring boot. Pistän tähän taas muistiinpanoja kokeiluistani.

Disclaimer: Vaikka Spring on monen mielestä legacymoskaa ja puhdas Java EE vaihteeksi pop, se tarjoaa edelleenkin muutaman houkuttavan argumentin ketterän projektin kannalta – kuten kyky asentaa softa vaikka tomcat palvelimille (joista löytyy esim. Amazon klusterista helpot valmisasennukset) – kyky ymmärtää ja hallita mekanismeja eri tavalla kuin sovelluspalvelinten mystiset automatiikat toimivat – ja ennen kaikkea mahtava tuki hollywood principlelle ja aop:lle – joka taas tarjoaa hienosti isolaatiota ja sitä myöden yksikkötestattavuutta, sitä myöden nopeita testejä, sitä myöden kehittäjätestejä ja testikattavuutta – sitä myöden speksejä ja toimintavarmuutta – sitä myöden business arvoa. Eli jeah, ei Springin hautajaisia vielä ole pidetty.

Vaihe 1: Tarvitaan kansio projektille, ja pom.xml. Tämmöinen:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
<groupId>com.whatever</groupId>
 <artifactId>myproject</artifactId>
 <version>0.0.1-SNAPSHOT</version>
<parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>1.1.0.BUILD-SNAPSHOT</version>
 </parent>
 <!-- (you don't need this if you are using a .RELEASE version) -->
<repositories>
 <repository>
 <id>spring-snapshots</id>
 <url>http://repo.spring.io/snapshot</url>
 <snapshots>
 <enabled>true</enabled>
 </snapshots>
 </repository>
 <repository>
 <id>spring-milestones</id>
 <url>http://repo.spring.io/milestone</url>
 </repository>
 </repositories>
 <pluginRepositories>
 <pluginRepository>
 <id>spring-snapshots</id>
 <url>http://repo.spring.io/snapshot</url>
 </pluginRepository>
 <pluginRepository>
 <id>spring-milestones</id>
 <url>http://repo.spring.io/milestone</url>
 </pluginRepository>
 </pluginRepositories>
</project>

 

Jep, ja vertavuotavalla terällä tässä mennään. Eli bootin epävirallisella snapshot versiolla joka on liikkeessä. Mutta mielummin terällä kuin terän alla.

Päräytetäänpä tässä vaiheessa mvn package. Hmm tottakai esivaatimuksena Java asennettuna (8 tottakai), ja Maven, ja molemmat komentopolussa. Tai voit avata tämän projektin vaikka Netbeans Open toiminnolla, jossa pom tiedostoa onkin mukavampi editoida.

Tämä ei vielä paljoa tee. Lisätään web dependency:

<dependencies>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-web</artifactId>
 </dependency>
 </dependencies>

Aja uudelleen mvn package. Nyt paukkuu vähän enemmän latauksia – verkosta ladataan perus-spring-web projektin tarvittavat riippuvuudet. Niitä on paljon (Spring jar helvetti). Ja hups, tässä tuli mukana myös Tomcat.

Päräytetään REST palvelu paikalleen. Naputa tai kopioi tämä maven lähdekoodikansioon (src/main/java – joudut varmaan luomaan tämän kansiorakenteen, koska boot ei sitä automaattisesti tee. Ja Mavenhän vaatii Javan olevan juuri tuon polun alla. Saa tehdä paketin jos erityisesti kutkuttaa.):

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

    @RequestMapping("/")
    String home() {
        return "Hello World!";
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Example.class, args);
    }

}

Nyt sitten nopeaan testaukseen. Tarkista ensin ettei ole käynnissä palvelimia portissa 8080 (sammuta Glassfish 😉

Aja seuraava komento:

mvn spring-boot:run

Tämä potkaisee käyntiin tomcatin ja voit kokeilla sitä selaimella osoitteessa http://localhost:8080/

Toimiiko? Mahtavaa, en olisi uskonut. REST servicehän se sieltä kurkkii.

Serverin voi ajaa alas Ctrl+C

Paketointi

Nyt voisi paukauttaa koko roskan-tomcatteineen kaikkineen boot .jar pakettiin. Lisää dependencies-osan alle tällainen plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Ja aja komentoriviltä:

maven package

Tadaa! target-kansioon syntyy uusi .jar joka sisältää tarvittavat riippuvuudet, voit ajaa sen komentoriviltä näin:

java -jar target/myproject-0.0.1-SNAPSHOT.jar

Kun kyllästyt leikkimään, Ctrl+C lopettaa taas.

Spring Boot Java taso on oletuksena 6. Voisi olla kiva käytellä Java 8 uusia piirteitä. Se onnistuu näin pom.xml:ssä:

<properties>
    <java.version>1.8</java.version>
</properties>

Ja jos haluat käyttää myös Tomcat 8 versiota 7:n sijasta:

 <properties>
 <java.version>1.8</java.version>
 <tomcat.version>8.0.3</tomcat.version>
 </properties>

Yksi suositeltava parannus on jakaa initialisointi ja toiminnot eri tiedostoihin, voit tehdä esim. Application-tiedoston sovelluksesi pakettihierarkiaan tähän tapaan:

package com.myorg.myproj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

}

Ja näin tuo Example-luokka (joka olisi hyvä olla pakettihierarkiassa em. Application luokan alla) näyttäisi tältä:

package com.myorg.myproj.hello;

import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.stereotype.*;
import org.springframework.web.bind.annotation.*;

@RestController
public class Example {

  @RequestMapping("/")
   String home() {
    return "Hello World2!";
  }

}

Näin on helpompaa lisäillä uusia palveluita.

 

Yhden .jar paketin sovellus on melko kutkuttava, mutta käytännössä on tilanteita joissa olisi myös kiva saada .war ulos, tässä siihen vinkki:

Lisää pom.xml tiedostoon:

<packaging>war</packaging>

Nyt on syytä samantien muuttaa tomcat riippuvuuden scope moodiin ’provided’ – muuten se paketoidaan myös .war paketin sisään toiseen kertaan. Jos sinulla ei ole tätä riippuvuutta vielä, sen voi silti lisätä provided-scopella dependencies-kohtaan:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

Tässä kohtaa voisit tehdä clean&build ja tiputella tomcat webapps-kansioon, mutta eipä toimi vielä. Alunperäisen ohjeen luokka nimittäin käytti main-metodia initialisointiin, joka sopii kyllä .jar pakettiin hienosti – mutta jota ei enää kukaan kutsu.

Joten lisäämme Servlet-luokan joka perii SpringBootServletInitializer-luokan, ja nykäisee Application-luokan taas käyntiin:

package com.whatever;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.web.SpringBootServletInitializer;

public class ApplicationInitializer extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(Application.class);
  }
}

Ja sitten vain mvn clean package, ja target-kansioon putkahtaa geneerinen .war jonka voi asentaa eri palvelimille.

Aika rouheita lisäosia ovat mm. JPA, Spring Data, MongoDB moduulit..

Ja enkunkielinen lähde – kannattaa ehdottomasti lukea esim. pykälä 13.2 koskien pakettien ja luokkien järjestelyn parhaita käytäntöjä.

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#getting-started-installing-spring-boot

 

 

 

Mainokset

Vastaa

Täytä tietosi alle tai klikkaa kuvaketta kirjautuaksesi sisään:

WordPress.com-logo

Olet kommentoimassa WordPress.com -tilin nimissä. Log Out / Muuta )

Twitter-kuva

Olet kommentoimassa Twitter -tilin nimissä. Log Out / Muuta )

Facebook-kuva

Olet kommentoimassa Facebook -tilin nimissä. Log Out / Muuta )

Google+ photo

Olet kommentoimassa Google+ -tilin nimissä. Log Out / Muuta )

Muodostetaan yhteyttä palveluun %s