spring framework ふりかえりと4.3新機能

42
Spring Framework ふりかえりと4.3新機能 木村 俊介 @kimullaa 1

Upload: kimulla

Post on 24-Jan-2018

1.903 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Spring Framework ふりかえりと4.3新機能

Spring Frameworkふりかえりと4.3新機能木村 俊介 @kimullaa

1

Page 2: Spring Framework ふりかえりと4.3新機能

自己紹介

名前:木村俊介(きむらしゅんすけ)

仕事: SI企業の技術部隊@2013

フレームワーク整備と展開、PJ支援

2年前までは Struts + EJB + iBatis ベースの自社FW

現在は Spring + MyBatis を社内に推進、展開

Spring歴: 2年くらい

2

Page 3: Spring Framework ふりかえりと4.3新機能

今日のテーマ

基礎をふりかえりながら、Spring Framework 4.3 の新機能をご紹介

『Modern Java Component Design with Spring Framework 4.3』- モダンなSpringの使い方と新機能の説明- スライド- 動画

『Spring MVC 4 Web Apps』- WEB機能(Spring MVC)に絞った新機能の説明- スライド- 動画まだ上がってません

Juergen Hoeller

Rossen Stoyanchev

3

Page 4: Spring Framework ふりかえりと4.3新機能

既に話しつくされたネタ感

@Shimizuさんの日本語解説ブログ

http://qiita.com/kazuki43zoo/items/172d132ff8f4ba098888#core-

container-improvements

JSUG勉強会 2016年その4 Spring I/O報告会池谷さんの発表

http://ikeyat.github.io/slides-

publish/slides/201606XX_SpringIO2016Summary/#1

JJUG CCC 2016 Spring @makingさんの発表

http://sssslide.com/www.slideshare.net/makingx/jjugccc-cccgh5-whats-

new-in-spring-framework-43-boot-14-pivotals-cloud-native-approach

Spring Framework リファレンス

http://docs.spring.io/spring/docs/current/spring-framework-

reference/html/new-in-4.3.html

4

Page 5: Spring Framework ふりかえりと4.3新機能

でもやります

5

Page 6: Spring Framework ふりかえりと4.3新機能

知ってる人は知っている

6

Page 7: Spring Framework ふりかえりと4.3新機能

知らない人は覚えてね

7

Page 8: Spring Framework ふりかえりと4.3新機能

Spring Framework ふりかえり

8

Page 9: Spring Framework ふりかえりと4.3新機能

DIコンテナ

Dependency Injection

Beanの登録

- Java Config- アノテーションベース- XMLベース

Bean BeanBean

Bean Bean

lookup

依存性の解決 メリット:テスタビリティ向上、ライフサイクル管理

9

Page 10: Spring Framework ふりかえりと4.3新機能

Aspect Oriented Programming

AOP

AOP

クラスA クラスB

横断的関心事の分離メリット:コード量削減、見通しのよいコード

ログ出力、Tx管理

10

Page 11: Spring Framework ふりかえりと4.3新機能

で、こうなる

11

Page 12: Spring Framework ふりかえりと4.3新機能

Java Config + アノテーションベース

@Configuration // Java Configの宣言@Profile(“standalone”) // standaloneプロファイル時に有効になる@EnableTransactionManagement // SpringによるTx管理を有効化@ComponentScan(“com.example”) // スキャン&Bean登録

public class AppConfig {

@Bean // Bean定義

public FooService fooService() {// CGLibでUtilityのインスタンスは1度しか生成されない

return new FooServiceImpl(utility());

} @Bean // Bean定義

public Utility utility() {return new Utility();}

}

~4.2

12

Page 13: Spring Framework ふりかえりと4.3新機能

@Configuration

public class AppConfig implements FooAppConfig {

…// デフォルトメソッドのBean定義が有効になる

}

public interface FooAppConfig {

@Bean

default FooService fooService() {

return new FooServiceImpl();

}

}

~4.2

13

Java Config & Java8

Page 14: Spring Framework ふりかえりと4.3新機能

@Component class

@Service // ComponentScan時にBean登録される@Lazy // Lazy-load(利用時にインスタンス化)

public class FooServiceImpl implements FooService {

private final FooRepository fooRepository;

@Autowired // コンストラクタインジェクション

public FooServiceImpl(FooRepository fooRepository) {

this. fooRepository = fooRepository;

}

@Transactional // AOPでトランザクション管理

public void update() {

}

~4.2

14

Page 15: Spring Framework ふりかえりと4.3新機能

Lazy Injection Points

@Bean @Lazy

public FooRepository fooRepository () {

return new FooRepositoryImpl();

}

@Service

public class FooServiceImpl implements FooService {

private final FooRepository fooRepository ;

@Autowired // 依存先のBeanに関係なく@Lazyを有効化できるpublic FooServiceImpl(@Lazy FooRepository fooRepository ) {

this. fooRepository = fooRepository ;

}

}

~4.2

15

Page 16: Spring Framework ふりかえりと4.3新機能

合成アノテーション

@Service

@Scope(“session”)

@Primary

@Transactional(rollbackFor = Exception.class, timeout = 30)

public @interface MyCustomService {}

@MyCustomService

public class FooServiceImpl implements FooService {

}

アノテーションを組み合わせられる

~4.2

16

Page 17: Spring Framework ふりかえりと4.3新機能

合成アノテーション属性の上書き

@Service

@Scope(“session”)

@Primary

@Transactional(rollbackFor = Exception.class, timeout = 30)

public @interface MyCustomService {

@AliasFor(annotation = Transactional.class, attribute = “readOnly”)

boolean readOnly() default false;

}

@MyCustomService(readOnly=false)

public class FooServiceImpl implements FooService { … }

上書きしたい属性だけ公開できる

~4.2

17

Page 18: Spring Framework ふりかえりと4.3新機能

Spring Framework 4.3

18

Page 19: Spring Framework ふりかえりと4.3新機能

Spring Framework 4.3

4系のラストリリース(リリース済み)

2019年までサポート

SpringBoot 1.4 のデフォルト

『SpringOne Platform 2016 keynote』より引用

19

Page 20: Spring Framework ふりかえりと4.3新機能

Spring Framework 4.3 改善点

Core Container Improvements

Web Improvements

Data Access Improvements

Caching Improvements

JMS Improvements

WebSocket Messaging Improvements

Testing Improvements

今日話すことはこの中の一部

20

Page 21: Spring Framework ふりかえりと4.3新機能

Core Container Improvements

21

Page 22: Spring Framework ふりかえりと4.3新機能

1. 暗黙的なコンストラクタインジェクション

@RestController

public class Foo {

private final HogeService hogeService;

private final FugaService fugaService;

// @Autowired

public Foo(HogeService hogeService, FugaService fugaService) {

this.hogeService = hogeService;

this.fugaService = fugaService;

}

4.3

コンストラクタが1つなら省略可能

22

Page 23: Spring Framework ふりかえりと4.3新機能

2. Java Config クラスでコンストラクタインジェクション

@Configuration

public class AppConfig {

private final Utility utility;

// @Autowiredが書けるようになった(けど省略可能)

public AppConfig(Utility utility) {

this.utility = utility;

}

@Bean

public FooService fooService() {

return new FooServiceImpl(this.utility);

}

}

4.3

23

Page 24: Spring Framework ふりかえりと4.3新機能

3. InjectionPoint like CDI

『http://sssslide.com/www.slideshare.net/makingx/jjugccc-cccgh5-whats-new-in-spring-framework-43-boot-14-pivotals-cloud-native-approach』より引用

4.3

4.3

24

Page 25: Spring Framework ふりかえりと4.3新機能

活用例. Loggerの生成

public class HelloController {

@Autowired

private Logger logger; //= LoggerFactory.getLogger(HelloController.class)

public void log(){ // … com.example.controllers.HelloController : hello と表示される

logger.info(“hello”);

}

}

@Configuration

public class AppConfig {

@Bean @Scope(value="prototype“, proxyMode = ScopedProxyMode.NO)

Logger getLogger(InjectionPoint ip ) {

return LoggerFactory.getLogger(

ip.getMember().getDeclaringClass().getName()); }

}

4.3

proxyModeがNOなので、自身のスコープよりも広いBeanにインジェクトされると、依存先のスコープになる(CDIの@Dependentみたいなスコープ)

25

Page 26: Spring Framework ふりかえりと4.3新機能

@RestController

@Slf4j

public class HelloController {

// Logger log = LoggerFactory.getLogger(HelloController.class);

public void log(){ // … com.example.controllers.HelloController : hello と表示される

log.info(“hello”);

}

}

4.3

コンパイル時に暗黙的に生成される

ただ、lombokはもっとすごい

詳細は TERASOLUNA Server Framework を参照

http://terasolunaorg.github.io/guideline/5.2.0.RELEASE/ja/Appendix/Lombok

.html#lombokhowtouselogger

26

Page 27: Spring Framework ふりかえりと4.3新機能

4. Generics-based Injection

@Service

public class HogeServiceImpl implements HogeService {

@Resource(name = “listFoo”) private List<Foo> listFoo;

@Resource(name = “listBar”) private List<Bar> listBar;

}

@Configuration

public class AppConfig {

@Bean(name = “listFoo”)

public List<Foo> fooList(){…}

@Bean(name = “listBar”)

public List<Bar> fooList(){…}

}

型ではなく名前で解決@Autowired ではなく @Resource

http://docs.spring.io/spring/docs/4.2.7.RELEASE/spring-framework-reference/htmlsingle/#beans-

autowired-annotation-qualifiers

~4.2

27

Page 28: Spring Framework ふりかえりと4.3新機能

4. Generics-based Injection

@Service

public class HogeServiceImpl implements HogeService {

@Autowired List<Foo> listFoo;

@Autowired List<Bar> listBar;

}

@Configuration

public class AppConfig {

@Bean

public List<Foo> fooList(){…}

@Bean

public List<Bar> barList(){…}

}

4.3

型で解決

28

Page 29: Spring Framework ふりかえりと4.3新機能

Web Improvements

29

Page 30: Spring Framework ふりかえりと4.3新機能

@GetMapping

@PostMapping

@PutMapping

@DeleteMapping

@PatchMapping

@OptionsMapping

@HeadMapping

1. @RequestMappingの合成アノテーション

理由はあとで

30

Page 31: Spring Framework ふりかえりと4.3新機能

@GetMappingの例

@RequestMapping(value = “hello” , method = RequestMethod.GET)

public String hello(){ … }

@GetMapping(value = “hello”)

public String hello(){ … }

4.3

可読性があがったタイプ数が減った

~4.2

31

Page 32: Spring Framework ふりかえりと4.3新機能

2. HEAD, OPTIONS の自動サポート

$ curl -i -X OPTIONS http://localhost:8080/hello

HTTP/1.1 200

X-Application-Context: application

Allow: GET,HEAD

Content-Length: 0

Date: Sun, 28 Aug 2016 07:32:23 GMT

$ curl -i --head http://localhost:8080/hello

HTTP/1.1 200

X-Application-Context: application

Content-Type: text/plain;charset=UTF-8

Content-Length: 4

Date: Sun, 28 Aug 2016 07:40:25 GMT

Allowヘッダに対応可能なHTTPメソッドが列挙される。Controllerのメソッドは実行されない。

GETメソッドと同じ。ただしレスポンスボディは空Controllerのメソッドが実行される。

GET付与でHEADとOPTIONSが自動サポート定義方法は@RequestMappingでも@GetMappingでもok

32

Page 33: Spring Framework ふりかえりと4.3新機能

3. Webスコープに関する@Scopeの合成アノテーション

@RequestScope

@SessionScope

@ApplicationScope

スコープ 内容

prototype Bean参照ごとに毎回生成

request HTTPのリクエストごとに生成

session ユーザセッションごとに生成

singleton ApplicationContextごとに生成

application ServletContextごとに生成広い

狭い

33

Page 34: Spring Framework ふりかえりと4.3新機能

@RequestScope の例

@Component

@Scope(scopeName = “request”, proxyMode = TARGET_CLASS)

public class Foo { … }

@Component

@RequestScope

public class Foo { … }

4.3

可読性があがったタイプ数が減った

~4.2

34

Page 35: Spring Framework ふりかえりと4.3新機能

他のスコープを作ってみる

@Target({ElementType.TYPE, ElementType.METHOD})

@Retention(RetentionPolicy.RUNTIME)

@Documented

@Scope("prototype")

public @interface PrototypeScope {

@AliasFor(annotation = Scope.class)

ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

}

@Component

@PrototypeScope

public class Foo { … }

重要なのはここだけ合成アノテーションは簡単

35

Page 36: Spring Framework ふりかえりと4.3新機能

4. @RestControllerAdvice

@ControllerAdvice

public class GlobalHandler {

@ExceptionHandler(Exception.class)

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)

@ResponseBody

public Foo handle(){…}

@RestControllerAdvice

public class GlobalHandler {

@ExceptionHandler(Exception.class)

@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)// @ResponseBodyが不要

public Foo handle(){…}

4.3@ControllerAdvice + @ResponseBody

~4.2

36

Page 37: Spring Framework ふりかえりと4.3新機能

5. @RequestAttribute

@RequestMapping(value = “foo”, method = RequestMethod.GET)

public String foo(HttpServletRequest request) {

String param1 = (String) request.getAttribute(“param1”);

… }

@RequestMapping(value = “foo”, method = RequestMethod.GET)

public String foo(@RequestAttribute(“param1”) String param1){…}

4.3

Servlet API に依存せずに取得できる

~4.2

37

Page 38: Spring Framework ふりかえりと4.3新機能

6. @SessionAttribute

@RequestMapping(value = “foo”, method = RequestMethod.GET)

public String foo(HttpSession httpSession) {

String param1 = (String) httpSession.getAttribute(“param1”);

… }

@RequestMapping(value = “foo”, method = RequestMethod.GET)

public String foo(@SessionAttribute(“param1”) String param1){…}

4.3

Servlet API に依存せずに取得できる

~4.2

38

Page 39: Spring Framework ふりかえりと4.3新機能

7. @ModelAttribute(binding = false)

@ModelAttribute

public Book setUpBook() {// おすすめの本の取得

return new Book(“spring”);

}

@PostMapping(“purchase”)

public void purchase (BookForm form,

@ModelAttribute(binding = false) Book book) {

}

4.3

リクエストパラメータのバインドを抑制する

リクエストパラメータがバインドされる(titleはjavaee)

リクエストパラメータをバインドせずにModelの値を取得する(titleはspring)

curl –X POST localhost:8080/purchase?title=javaee

Bookクラス、BookFormクラスはtitleフィールドを持つとする

39

Page 40: Spring Framework ふりかえりと4.3新機能

おわりに

40

Page 41: Spring Framework ふりかえりと4.3新機能

詳細はここ

@Shimizuさんの日本語解説ブログ

http://qiita.com/kazuki43zoo/items/172d132ff8f4ba098888#core-

container-improvements

JSUG勉強会 2016年その4 Spring I/O報告会池谷さんの発表

http://ikeyat.github.io/slides-

publish/slides/201606XX_SpringIO2016Summary/#1

JJUG CCC 2016 Spring @makingさんの発表

http://sssslide.com/www.slideshare.net/makingx/jjugccc-cccgh5-whats-

new-in-spring-framework-43-boot-14-pivotals-cloud-native-approach

Spring Framework リファレンス

http://docs.spring.io/spring/docs/current/spring-framework-

reference/html/new-in-4.3.html

41

Page 42: Spring Framework ふりかえりと4.3新機能

42

Javaは、Oracle Corporation及びその子会社、関連会社の米国及びその他の国における登録商標です。TERASOLUNAはエヌ・ティ・ティ・データにおける登録商標です。その他、記載されている会社名、商品名等は各社の商標または登録商標である場合があります。