• 2019年5月1日水曜日
アリスト戦記
アリスト戦記 https://blog.aristo-solutions.net/2019/05/javatemplatebatchspringboot.html

SpringBootはバッチでも使用出来るんだぞ

現在、Java界で一番隆盛を極めているライブラリはSpringBootではないだろうか?

SpringBootは、Java界の金字塔フレームワーク「Spring Framework」の系譜を受け継ぐライブラリで、Spring Frameworkと同じような機能を持ちながらSpring Frameworkよりも簡単に開発出来る。

JavaでのWebシステム開発なら第一はコレ。
SpringBootがあればJavaで綺麗なWebアプリが開発出来る……って、そうじゃねえよ(泣)

SpringBootはWebフレームワークではない!!

とんでもない勘違いをしていると思わしきプロダクトが目の前にあるんだけど、SpringBootはWebフレームワークじゃないからな!!

それはSpring Boot Web Starterという拡張パックだろ。

今の時代、現場開発の多くはWebだから「Webシステム開発を使う時に登場するフレームワーク」と覚えてしまっている人がいるみたいだけど、そうじゃない!!

SpringBootの本家は「DI(Dependency Injection):依存性注入」の方だ。

それを知らないヤツが「バッチ開発ならSpringBootは使えないよね」とでも勘違いして変なプロジェクトを作ってしまったとしか思えないソースがある。

その辺の経緯を説明しよう。

Java黎明期の二大フレームワーク

そもそも過去を振り返ると15年くらい前……、僕が社会人デビューしたのは2007年だったけど、その時点である有名な2つのフレームワークが存在した。


  • SpringFramework
  • Struts1


当時のJava界では、Webフレームワークと言えばStrus1の一強だった。
と言うよりも、昔のJavaは現在ほど盤石な評価を得ていなくて、色々ある言語の中の一つに過ぎなかったんだけど、Strus1の大人気により、一気にプログラミング言語界の首魁の座を手にした。

ファミコンってのはスーパーマリオブザーズの大人気で普及したでしょ?
JavaはStruts1の人気で普及した。
それくらいStruts1はキラーコンテンツだった。

その頃、同時期に存在していたのがSpringFrameworkだ。

SpringFrameworkは「DI(Dependency Injection):依存性注入」という機能を持っており、これが難しくて説明していると記事が終わらんからすっ飛ばすんだけど、早い話、Hibernateを使用する為に必要だったんだ。



  • Struts1 + Hibernate



これがJava界の史上最強のコンビネーション。
ベテランから新人までみんな意味分からず何となくこの構成を選んだ為、デスマ+クソソースの必殺コンボが多いことも特徴。
古のソルジャー達が愛用したAK-47のような伝説の構成である。

それはさておき、依存性注入は難しくて意味分からないからみんな雰囲気で使っていただけなんだけど、直球のORマッパーであるHibernateは絶対に必要で、その価値も分かり易いものだった。

みんなHibernate欲しさにSpringを導入した。
当時、SpiringはHibernateを使う時に一緒についてくる謎のライブラリ程度の認識で開発している現場が多かった。

最低だな!!

Struts1の衰退とSpringの拡張

その後、Struts1はその設定の煩雑さから衰退し、同時期にRubyの「Ruby On Rails」が登場した。

Ruby On Railsは「設定より規約」というキャッチフレーズで簡単にWebシステムが作れることが売りのライブラリで、今ではその思想は非常に一般的に普及しているんだけど、当時は極めて斬新な思想と評価されていた。

現場目線では、Ruby On Railsの「設定より規約」は、「Struts1の煩雑な設定xmlから解放される」というニュアンスだったわけよ。
これにより、Web開発はJavaではなくてRubyにしようか、と乗り換える人が沢山現れたんだ。
PHPと並ぶJavaのライバル登場だった。

しかしその頃、Springは新たな進化を遂げる。
Spring配下に別のWebフレームワークを加えることで、Spring単体でもWebシステム開発が出来るだけの機能が備わったんだ。


SpringにWebフレーム機能が加わったのは、後年の拡張である。


その後もSpringは進化を続け、今やより簡単に開発可能になったSpringBootというパッケージを生み出すに至る。

ここまで説明するとお分かり頂けるだろう。

SpringBootはSpringFrameworkの改善キットみたいなものであり、正体はSpringFramework本体と全く同一なわけよ。

そして歴史的背景を振り返ると、やっぱりその真価な部分は「DI(Dependency Injection):依存性注入」の方にある。

Webフレームワーク機能はオマケだ。

別にStruts2とかと併用しても良いんだけど、「SpringBoot単体で済ませられるならそれで良いんじゃない?」くらいの気分で採用するものである。

バッチでSpringBoot

そういう歴史を知っていると、当然、こういう発想になる。


「バッチでもSpringBootを使おうかな」


そうすれば、バッチでも「DI(Dependency Injection):依存性注入」を使用可能になる。
むしろバッチ開発の方がDIは綺麗に使えるのではないだろうか。

サンプル

ソース

バッチでSpringBootを起動するソースはこんな感じ。

/**
 * SpringBootのDIコンポーネントを使用してバッチをスタートするサンプルです。
 *
 * @author アリストマスター
 *
 */
@SpringBootApplication
public class SpringBootApplicationExecuter extends AbstractExecuter {

   /** logger */
   private static final Logger log = LoggerFactory.getLogger(SpringBootApplicationExecuter.class);

   /**
    * @param args
    * @throws Exception
    */
   public static void main(String[] args) throws Exception {

      ConfigurableApplicationContext context = SpringApplication.run(SpringBootApplicationExecuter.class, args);

      SpringBootApplicationExecuter exe = context.getBean(SpringBootApplicationExecuter.class);
      exe.start(args);

   }

   @Override
   public void doStart(String[] args) {

      log.info("SpringBootを経由してインスタンスを作成しました。");

   }

}

特徴はココ。
普通ならnewでインスタンスを作成している部分をこういう風に書くことでSpringBootのDIコンテナとして作り出すことが可能になる。

      ConfigurableApplicationContext context = SpringApplication.run(SpringBootApplicationExecuter.class, args);
      SpringBootApplicationExecuter exe = context.getBean(SpringBootApplicationExecuter.class);
      exe.start(args);


以後はWebのサービスクラスの開発と同じような感じで実装出来る。


pom.xml

上記ソースで動作確認した現時点でのpom.xmlを以下に貼っておく。


<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>

   <parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.1.4.RELEASE</version>
      <relativePath /> <!-- lookup parent from repository -->
   </parent>

   <groupId>net.aristo.template</groupId>
   <artifactId>AristJavaTemplateBatch</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>AristJavaTemplateBatch</name>
   <url>http://maven.apache.org</url>

   <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <java.version>1.8</java.version>
      <maven.compiler.target>${java.version}</maven.compiler.target>
      <maven.compiler.source>${java.version}</maven.compiler.source>
   </properties>

   <dependencies>
      <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter -->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter</artifactId>
      </dependency>

      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <scope>test</scope>
      </dependency>
      <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
      </dependency>
      <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-core</artifactId>
      </dependency>
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
      </dependency>
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>jcl-over-slf4j</artifactId>
      </dependency>
      <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>log4j-over-slf4j</artifactId>
      </dependency>

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

終わりに

さて、これでようやくバッチ作りの基底部分が出来上がったかな。

SpringBootはバッチのクラス設計全体に影響を与える基幹ライブラリだから、作り始める時に最初にガチッと固めておかなければならない。

「DI(Dependency Injection):依存性注入」の使い道は追って別の記事にする。

0 件のコメント:

コメントを投稿