Spring I/O 2016報告会

2016/6/22 JSUG

自己紹介

agenda

Spring 4.3の新機能

Spring4.3

Spring 4.3の新機能

making

紹介するSpring 4.3の新機能

分類 新機能
Container コンストラクタの@Autowired省略に対応
Web 各種合成アノテーションの提供
暗黙的なHEADとOPTIONSのレスポンス作成
@SessionAttribute@RequestAttributeの追加
Boot/Test 別セッションで

コンストラクタの@Autowired省略

@Service
public class MyBookService {
  private MyBookRepository repository;

  // @Autowired <- 省略可能となった
  public MyBookService(MyBookRepository repository) {
    this.repository = repository;
  }
}

コンストラクタの@Autowired省略

// @RequiredArgsConstructor(onConstructor = @__(@Autowired)) 
// @Autowiredをコンストラクタに付けるために必要だった呪文が不要に
@Service
public class MyBookService {
  private MyBookRepository repository;

  // コンストラクタがLombokによりコンパイル時に生成される
}

各種合成アノテーションの提供1

// Before
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String getBooks() {...}

// After
@GetMapping("/books")
public String getBooks() {...}

各種合成アノテーションの提供2

// Before
@Scope(value = WebApplicationContext.SCOPE_SESSION,
        target = ScopedProxyMode.TARGET_CLASS)
public class SessionScopedService { ... }

// After
@SessionScope
public class SessionScopedService { ... }

暗黙的なHEADとOPTIONSのレスポンス作成

@GetMapping("/books")
public String getBooks() {...}
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET,HEAD
...

@SessionAttribute@RequestAttributeの追加

// Before
@RequestMapping(value = "/books", method = RequestMethod.GET)
public String getBooks(HttpSession session) {
   String id = (String) session.getAttribute("bookId");
   // ...
}

// After
@RequestMapping("/books")
public String getBooks(@SessionAttribute("bookId") String bookId) {
   String id = bookId;
   // ...
}

Spring 4.3 個人的な感想

agenda

Spring Dataの新機能

SpringData

そもそもSpring Dataとは

SpringData

そもそもSpring Dataとは

Release Spring Commons JPA GemFire MongoDB
Ingalls 4.3? 1.13.x? 1.11.x? 1.9.x? 1.10.x?
Hopper 4.2 1.12.x 1.10.x 1.8.x 1.9.x
Gosling 4.1 1.11.x 1.9.x 1.7.x 1.8.x
Fowler 4.0 1.10.x 1.8.x 1.6.x 1.7.x

そもそもSpring Dataとは

public interface BookRepository extends CrudRepository<Book, Long> {}

public class BookService {
    @Autowired
    BookRepository repository;

    @Transactional(readOnly = true)
    public Book getBook(Long id) {
        return repository.findOne(id);
    }
}

Spring Dataの新機能

Java SE8 Stream APIへの対応

public interface PersonRepository
         extends CrudRepository<Person, String> {
  // Before
  @Query("SELECT p FROM person p")
  List<Person> findAllWithList();
  // After
  @Query("SELECT p FROM person p")
  Stream<Person> findAllWithStream();
}

Java SE8 Stream APIへの対応

// Before (All records are fetched before streaming)
List<Person> list = repository.findAllWithList();
list.stream().forEach(System.out::println);

// After (Fetched one by one)
repository.findAllWithStream().forEach(System.out::println);

Query by Exampleのサポート

// last nameが"White"のユーザを検索するクエリ
Example<User> example = Example.of(new User(null, "White", null));
int countMatches = userRepository.count(example);
List<User> usersMatches = userRepository.findAll(example);
public interface UserRepository
         extends CrudRepository<User, String>,
                 QueryByExampleExecutor<User> {
}

Projectionsのサポート

@Entity
public class Person {
  @Id @GeneratedValue private Long id;
  private String firstName, lastName;
  private String street, state, country;
  // …
}
// Before
Person person = personRepository.findOne(id);
String fullName = person.getFirstName() + " " + person.getLastName();

Projectionsのサポート

public interface FullName {
  @Value("#{target.firstName} #{target.lastName}")
  String getFullName();
}

public interface PersonRepository
        extends CrudRepository<Person, Long> {
  FullName findProjectedById(Long id);
}
// After
String fullName = personRepository.findProjectedById(id).getFullName();

agenda

Spring Integrationを使ってみよう

SpringIntegration

Spring Integrationとは

SpringIntegration

Spring Integrationとは

Spring Integrationの実装例

SpringIntegration

Spring Integrationの実装例(xml)

<file:inbound-channel-adapter id="filesIn"
    directory="file:xxx/input">
  <integration:poller id="poller" fixed-delay="5000"/>
</file:inbound-channel-adapter>

<integration:service-activator input-channel="filesIn"
    output-channel="filesOut"
    ref="handler" method="handle" />

<file:outbound-channel-adapter id="filesOut"
    directory="file:xxx/output"
    delete-source-files="true"/>

<bean id="handler" class="com.example.Handler"/>

Spring Integrationの実装例(Handler)

public class Handler {
    public String handle(String payload) {
        System.out.println("Copying text: " + payload);
        return payload.toUpperCase();
    }
}

Spring I/Oでのデモのポイント