View
1.903
Download
0
Category
Preview:
Citation preview
Spring Frameworkふりかえりと4.3新機能木村 俊介 @kimullaa
1
自己紹介
名前:木村俊介(きむらしゅんすけ)
仕事: SI企業の技術部隊@2013
フレームワーク整備と展開、PJ支援
2年前までは Struts + EJB + iBatis ベースの自社FW
現在は Spring + MyBatis を社内に推進、展開
Spring歴: 2年くらい
2
今日のテーマ
基礎をふりかえりながら、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
既に話しつくされたネタ感
@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
でもやります
5
知ってる人は知っている
6
知らない人は覚えてね
7
Spring Framework ふりかえり
8
DIコンテナ
Dependency Injection
Beanの登録
- Java Config- アノテーションベース- XMLベース
Bean BeanBean
Bean Bean
lookup
依存性の解決 メリット:テスタビリティ向上、ライフサイクル管理
9
Aspect Oriented Programming
AOP
AOP
クラスA クラスB
横断的関心事の分離メリット:コード量削減、見通しのよいコード
ログ出力、Tx管理
10
で、こうなる
11
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
@Configuration
public class AppConfig implements FooAppConfig {
…// デフォルトメソッドのBean定義が有効になる
}
public interface FooAppConfig {
@Bean
default FooService fooService() {
return new FooServiceImpl();
}
}
~4.2
13
Java Config & Java8
@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
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
合成アノテーション
@Service
@Scope(“session”)
@Primary
@Transactional(rollbackFor = Exception.class, timeout = 30)
public @interface MyCustomService {}
@MyCustomService
public class FooServiceImpl implements FooService {
…
}
アノテーションを組み合わせられる
~4.2
16
合成アノテーション属性の上書き
@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
Spring Framework 4.3
18
Spring Framework 4.3
4系のラストリリース(リリース済み)
2019年までサポート
SpringBoot 1.4 のデフォルト
『SpringOne Platform 2016 keynote』より引用
19
Spring Framework 4.3 改善点
Core Container Improvements
Web Improvements
Data Access Improvements
Caching Improvements
JMS Improvements
WebSocket Messaging Improvements
Testing Improvements
今日話すことはこの中の一部
20
Core Container Improvements
21
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
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
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
活用例. 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
@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
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
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
Web Improvements
29
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
@OptionsMapping
@HeadMapping
1. @RequestMappingの合成アノテーション
理由はあとで
30
@GetMappingの例
@RequestMapping(value = “hello” , method = RequestMethod.GET)
public String hello(){ … }
@GetMapping(value = “hello”)
public String hello(){ … }
4.3
可読性があがったタイプ数が減った
~4.2
31
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
3. Webスコープに関する@Scopeの合成アノテーション
@RequestScope
@SessionScope
@ApplicationScope
スコープ 内容
prototype Bean参照ごとに毎回生成
request HTTPのリクエストごとに生成
session ユーザセッションごとに生成
singleton ApplicationContextごとに生成
application ServletContextごとに生成広い
狭い
33
@RequestScope の例
@Component
@Scope(scopeName = “request”, proxyMode = TARGET_CLASS)
public class Foo { … }
@Component
@RequestScope
public class Foo { … }
4.3
可読性があがったタイプ数が減った
~4.2
34
他のスコープを作ってみる
@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
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
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
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
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
おわりに
40
詳細はここ
@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
42
Javaは、Oracle Corporation及びその子会社、関連会社の米国及びその他の国における登録商標です。TERASOLUNAはエヌ・ティ・ティ・データにおける登録商標です。その他、記載されている会社名、商品名等は各社の商標または登録商標である場合があります。
Recommended