PivotalのDeveloper AdvocateのJosh Long(@starbuxman)がSpring Boot 1.2とJava EEに関する面白い記事を書いていたので、本人の許可をとって翻訳してみました。わりとナチュラルに訳したつもりです。
元記事: "Bootiful" Java EE Support in Spring Boot 1.2
この記事では、Java EEを使っている人またはSpring Bootに移ろうとしている人の開発をより容易にするSpring Boot 1.2の_多くの_新機能を見ていきたいと思います。そしてデモしたいと思います。
これらのサポートはこれまでのSpringでも当然利用できるのですが、今回のSpring Boot 1.2を使用することでとびきり簡単になるということを言っておきたいです。
まず始めにサンプルプログラムをお見せします。説明はそれからです。
package demo;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsTemplate;
import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import javax.jms.JMSException;
import javax.persistence.*;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.io.Serializable;
import java.util.Collection;
import java.util.logging.Logger;
@SpringBootApplication
public class Application {
@Named
public static class JerseyConfig extends ResourceConfig {
public JerseyConfig() {
this.register(GreetingEndpoint.class);
this.register(JacksonFeature.class);
}
}
@Named
@Transactional
public static class GreetingService {
@Inject
private JmsTemplate jmsTemplate;
@PersistenceContext
private EntityManager entityManager;
public void createGreeting(String name, boolean fail) {
Greeting greeting = new Greeting(name);
this.entityManager.persist(greeting);
this.jmsTemplate.convertAndSend("greetings", greeting);
if (fail) {
throw new RuntimeException("simulated error");
}
}
public void createGreeting(String name) {
this.createGreeting(name, false);
}
public Collection<Greeting> findAll() {
return this.entityManager
.createQuery("select g from " + Greeting.class.getName() + " g", Greeting.class)
.getResultList();
}
public Greeting find(Long id) {
return this.entityManager.find(Greeting.class, id);
}
}
@Named
@Path("/hello")
@Produces({MediaType.APPLICATION_JSON})
public static class GreetingEndpoint {
@Inject
private GreetingService greetingService;
@POST
public void post(@QueryParam("name") String name) {
this.greetingService.createGreeting(name);
}
@GET
@Path("/{id}")
public Greeting get(@PathParam("id") Long id) {
return this.greetingService.find(id);
}
}
@Entity
public static class Greeting implements Serializable {
@Id
@GeneratedValue
private Long id;
@Override
public String toString() {
return "Greeting{" +
"id=" + id +
", message='" + message + '\'' +
'}';
}
private String message;
public String getMessage() {
return message;
}
public Greeting(String name) {
this.message = "Hi, " + name + "!";
}
Greeting() {
}
}
@Named
public static class GreetingServiceClient {
@Inject
private GreetingService greetingService;
@PostConstruct
public void afterPropertiesSet() throws Exception {
greetingService.createGreeting("Phil");
greetingService.createGreeting("Dave");
try {
greetingService.createGreeting("Josh", true);
} catch (RuntimeException re) {
Logger.getLogger(Application.class.getName()).info("caught exception...");
}
greetingService.findAll().forEach(System.out::println);
}
}
@Named
public static class GreetingMessageProcessor {
@JmsListener(destination = "greetings")
public void processGreeting(Greeting greeting) throws JMSException {
System.out.println("received message: " + greeting);
}
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
ソースコードは以上です。あとはちょっとしたapplication.properties
とMavenのビルドファイルがあるだけで、
これらはオンラインで参照可能です。
JerseyとJAX-RS
この例ではGreetingEndpoint
でBootの新機能であるJAX-RS自動設定をデモしています (この場合、Jersey 2.xを使っています) 。
めっちゃ簡単に動かせている点に注目していただきたいです!唯一面倒くさいのはResourceConfig
のサブクラスを作成して、Jerseyに登録するコンポーネントを知らせないといけない点ですね。
JTAによるグローバルトランザクション
新たにサポートされたJTA自動設定によるグローバルトランザクションもデモしています。JTAはX/Open XAプロトコルのためのJava APIで、(このプロトコルに :訳者注)準拠した複数のトランザクションリソース(メッセージキューやデータベース)を単一のトランザクションに参加させます。これを行うために、我々はスタンドアローンなJTAプロバイダーであるAtomikosを使用しました。同様に、Bitronixも簡単に利用できます。両方とも適切なstarterを持ってくれば自動設定されるのです。この例では、GreetingService
の中でJMSとJPAの処理がグローバルトランザクションの一部として機能しています。3つのトランザクションを生成し、3つめの処理をわざとロールバックさせています。これにより、2つのレコードがのJDBCのjavax.sql.DataSource
から取得され、2つのレコードが組み込みJMSのjavax.jms.Destination
に受信されていることがコンソールの出力から分かるでしょう。
組み込みWebサーバーUndertow
この例ではApache Tomcat(デフォルト)の代わりにWildFly (RedHat製) アプリケーションサーバーが持つ素晴らしいUndertow 組み込みHTTPサーバーを使用しています。Undertowを使うのは簡単でTomcatの代わりにJettyを使うのと同じように、(依存関係から :訳者注)org.springframework.boot:spring-boot-starter-tomcat
を除き、org.springframework.boot:spring-boot-starter-undertow
を追加するだけです!この対応はサードパーティのプルリクエストが元となっています。- Ivan Sopovサンクス! GJ!
諸々
(Java標準で :訳者注)統一感を出すために、この例ではJSR 330も使用しています。JSR 330では、WebLogicのようなプロプライエタリなアプリケーションサーバーでも、Google GuiceやSpringのようなDIコンテナでも同じように使えるようにするためのアノテーション群が決められています。またJSR 250のアノテーション(Java EE 5の一部として定義されました)も使用しています。これは(Beanの :訳者注)ライフサイクルにフックするデモを見せるためです。
この例では、Spring Bootで自動設定された組み込みインメモリH2のjavax.sql.DataSource
とa Spring Bootで自動設定された組み込みインメモリHornetQのjavax.jms.ConnectionFactory
に依存しています.
組み込みでないインスタンスに接続したければ、好きなものを直接Bean定義すればよいです。
また、この例では新しい@SpringBootApplication
アノテーションを使っています。これは@Configuration
と@EnableAutoConfiguration
と@ComponentScan
を一つにしたものです。ナイス!
デプロイ
この例ではJava EEの有名どころなAPIを沢山使っていますが、結局のところただのSpring Bootアプリケーションなのです。つまりデフォルトで、java -jar ee.jar
でアプリケーションを実行できますし、HerokuやCloud Foundryといったプロセス中心のplatforms-as-a-serviceに簡単にデプロイできます。
もしスタンドアローンなアプリケーションサーバー(Apache TomcaやWebSphereなど)にデプロイしたいのであれば、単純に.war
に変換し、Servlet 3対応のコンテナにデプロイすれば良いです。
もしより古典的なアプリケーションサーバーにデプロイするなら、代わりにSpring Bootはサーバーの機能をうまく利用できます。例えば、極めてシンプルに、JNDIからJMS ConnectionFactory
,やJDBC DataSource
、 JTA UserTransaction
を取得できます。
Spring Boot 1.2: 選択肢 と パワー
個人的には、これらの沢山のAPIには疑問をもっています。本当に、分散マルチリソーストランザクションが必要でしょうか?今日の分散化さされた世界においてグローバルトランザクションマネージャーを考えるのはアーキテクチャ的に臭いますね(リンク先の日本語訳 :訳者注)。SpringにはMVC、REST、HATEOS、OAuth、WebSocketがサポートされた、よりリッチで統合されたSpring MVCベースのスタックがあるのに、本当にJAX-RSを使いますか?JPAはSQLベースのjavax.sql.DataSource
とやり取りするためのナイスなAPIであるけれど、Spring Dataのリポジトリ(JPAサポートはもちろん、Cassandra、MongoDB、Redis、CouchBaseなどなど沢山の代替テクノロジー_も_サポートしている)は多くのボイラーポレートをなくしてくれるし、一般的なケースで利用可能なシンプルなインタフェースを提供しています。だから、本当にこれらの全てが必要なんですか?これはあなたがよくやってるであろうし、いつも通りのように、「選択はあなた次第」なのです。これがこのリリースがクールな理由です。よりパワーを、より選択肢を。
他には?
ぶっちゃけまだまだあります。 新機能がたくさんあります。全てのカバーをし始めるのもできなかったので、やりません。全てのスクープはリリースノートを確認してください!
Spring Boot 1.2はもうすぐGAになります。ちょっと試すのにちょうど良いタイミングです。issueをあげて、 質問してください!
という感じでJoshの記事を紹介してみました。Spring Boot 1.2面白いです。Java EEな方も是非お試しください。
Spring Boot 1.1の内容ですが、「はじめてのSpring Boot」もよろしく・・・