SlideShare a Scribd company logo
1 of 106
Download to read offline
SpringOne 2GX 2014 参加報告 
& Spring 4.1について 
JSUG勉強会 #jsug 
2014-12-11 Toshiaki Maki (@making)
自己紹介 
• @making 
• http://blog.ik.am 
• 公私ともにSpringヘービーユーザー 
• 日本Javaユーザーグループ幹事
祝「はじめてのSpring Boot」出版 
http://bit.ly/hajiboot
今日のコンテンツ 
• SpringOne 2gx 2014の様子 (5分) 
• Spring 4.1の新機能紹介 (45分)
今日話さないこと
SpringOne 2gx 2014の様子
SpringOne 2gx 2014 
• 2014/09/09~11 
• ダラス
SpringOne 2gx 2014 
• 5つのトラック約120セッション 
• Core Spring 
• Data & Integration 
•Web & JavaScript 
• Applied Spring 
• Big Data 
• http://www.slideshare.net/SpringCentral/tag/springone2gx2014
Dallas Omni Hotel
Food
Beers
先週銀座で飲んだ(どうでもいい)
Talk with Pivotal guys
Josh Long 
(@starbuxman)
効果 (1/2) 
http://spring.io/blog/2014/10/08/this-week-in-spring-october-7th-2014
効果 (2/2) 
http://spring.io/blog/2014/10/29/this-week-in-spring-october-28-2014 
!
会場めっちゃ寒かった 
景品のパーカー 
をもらうため会 
場に散らばった 
全てのバッジを 
必死で探したw
SpringOne 2gx 2015 
• 来年はワシントンで開催予定
Spring 4.1の新機能紹介
紹介するセッション 
http://www.slideshare.net/SpringCentral/tag/springone2gx2014
Spring 4.1 
• 2014年9月リリース 
• 現時点で4.1.3.RELEASE 
• メインストリームは4.2へ移行。 
4.1はメンテナンスモードへ 
Spring Bootは1.2から対応
Spring 4.1の主な新機能・改善 
Web機能の改善 
JMS機能の改善 
Cache機能の改善 
WebSocketメッセージング(STOMP)の改善 
Test機能の改善 
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/new-in-4.1.html
Spring 4.1の主な新機能・改善 
Web機能の改善 
JMS機能の改善 
Cache機能の改善 
WebSocketメッセージング(STOMP)の改善 
Test機能の改善 
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/new-in-4.1.html
Web機能の改善 
静的リソース制御の改善 
Controller引数のOptionalサポート 
Controllerの返値のListenableFutureサポート 
Jacksonの@JsonViewサポート 
JSONPサポート 
ResponseBodyAdvice追加 
新しいHttpMessageConverter追加 
EL関数 s:mvcUrl 追加 
ResponseEntityビルダーサポート 
GroovyMarkupTemplateサポート
Web機能の改善 
静的リソース制御の改善 
Controller引数のOptionalサポート 
Controllerの返値のListenableFutureサポート 
Jacksonの@JsonViewサポート 
JSONPサポート 
ResponseBodyAdvice追加 
新しいHttpMessageConverter追加 
EL関数 s:mvcUrl 追加 
ResponseEntityビルダーサポート 
GroovyMarkupTemplateサポート
静的リソースサポートの改善 
Spring MVC 4.1 
の目玉機能
説明に時間がかかる 
ので最後にまわす
Web機能の改善 
静的リソース制御の改善 
Controller引数のOptionalサポート 
Controllerの返値のListenableFutureサポート 
Jacksonの@JsonViewサポート 
JSONPサポート 
ResponseBodyAdvice追加 
新しいHttpMessageConverter追加 
EL関数 s:mvcUrl 追加 
ResponseEntityビルダーサポート 
GroovyMarkupTemplateサポート
Controller引数のOptionalサポート 
@RequestMapping(value = “/foo”) 
String foo(@RequestParam(required=false) String bar) { 
if (bar != null) { /* … */} 
} 
@RequestMapping(value = “/foo”) 
String foo(@RequestParam Optional<String> bar) { 
bar.map(value -> {/* … */}); 
} 
Before 
After
WebじゃないけどOptinal対応 
Before 
@Autowired(required=false) 
FooService fooService; 
After 
@Autowired 
Optional<FooService> fooService;
Jacksonの@JsonViewサポート 
interface PublicView {}; 
class User { 
@PublicView 
private String username; 
private String password; 
// … 
} 
@RestController 
class UserController { 
@RequestMapping("/user") 
@JsonView(PublicView.class) 
User getUser() { 
return new User("demo", "password"); 
} 
}
Jacksonの@JsonViewサポート 
interface PublicView {}; 
class User { 
@PublicView 
private String username; 
private String password; 
// … 
} 
@RestController 
class UserController { 
@RequestMapping("/user") 
@JsonView(PublicView.class) 
User getUser() { 
{"username":"demo"} 
return new User("demo", "password"); 
} 
}
JSONPサポート 
@ControllerAdvice 
public class JsonpAdvice extends 
AbstractJsonpResponseBodyAdvice { 
public JsonpAdvice() { 
super("callback"); 
} 
}
JSONPサポート 
@RestController 
class UserController { 
@RequestMapping("/user") 
User getUser() { 
return new User("demo", "password"); 
} 
} 
GET /user?callback=foo 
foo({"username":"demo", 
"password":"password"})
ResponseBodyAdvice 
• @ResponseBody/ResponseEntityメ 
ソッドへのコールバック 
• 2つの実装が組み込まれている 
• JsonViewResponseBodyAdvice 
• AbstractJsonpResponseBodyAdvice
新しいHttpMessageConverter追加 
GsonHttpMessageConverter 
軽量なJSONライブラリGSONを使用してHTTP経由で 
JSONをやりとり(通常はJacksonを使用する) 
ProtobufHttpMessageConverter 
HTTP経由でGoogleのシリアライゼーションフォーマッ 
トProtocol Bufferをやりとり 
MappingJackson2XmlHttpMessageConverter 
Jackson XMLを使用してHTTP経由でXMLをやりとり(通 
常はJAXBを使用する)
使い方 
従来のXMLの場合 
<mvc:annotation-driven> 
<mvc:message-converters> 
<bean class=“….GsonHttpMessageConverter” /> 
</mvc:message-converters> 
</mvc:annotation-driven> 
Spring Bootの場合 
@Configuration 
class AppConfig { 
@Bean 
HttpMessageConverter gsonHttpMessageConverter() { 
return new GsonHttpMessageConverter(); 
} 
}
ResponseEntityビルダーサポート 
Before 
public ResponseEntity<String> handle() { 
String body = "Hi!"; 
HttpHeaders headers = new HttpHeaders(); 
headers.setLocation(location); 
return new ResponseEntity(body, headers, 
HttpStatus.CREATED); 
} 
After 
public ResponseEntity<String> handle() { 
URI location = …; 
return ResponseEntity.created(location).body("Hi!"); 
}
RequestEntityビルダーサポート 
Before 
HttpHeaders headers = new HttpHeaders(); 
headers.setAccept(MediaType.APPLICATION_JSON); 
HttpEntity entity = new HttpEntity("Hi!", headers); 
restTemplate.exchange(uri, HttpMethod.POST, entity, 
String.class); 
After 
restTemplate.exchange(RequestEntity.post(uri) 
.accept(MediaType.APPLICATION_JSON) 
.body(Hi!), String.class);
EL関数 s:mvcUrl 追加 
@Controller 
@RequestMapping("/hotels/{hotel}") 
public class BookingController { 
@RequestMapping("/bookings/{booking}") 
String getBooking(@PathVariable Long booking) {/*…*/} 
} 
Before 
<a href="${pageContext.request.contextPath}/hotels/ 
21/42" /> 
After 
<a href="${s:mvcUrl('BC#getBooking').arg(0, 
42).buildAndExpand(21)}" />
URI逆引き 
static import MvcUriComponentsBuilder.*; 
UriComponents uriComponents = fromMethodCall( 
on(BookingController.class).getBooking(21) 
).buildAndExpand(42); 
URI uri = uriComponents.encode().toUri(); 
OR 
UriComponents uriComponents = 
fromMappingName("BC#getBooking") 
.arg(0, 21) 
.buildAndExpand(42); 
URI uri = uriComponents.encode().toUri();
Cacheの改善JMSの改善 
@JmsListenerサポート 
spring-messagingサポート 
JCache(JSR-107) サポート
Cacheの改善JMSの改善 
@JmsListenerサポート 
spring-messagingサポート 
JCache(JSR-107) サポート
@JmsListener 
Before (Spring 2~) 
@Component 
public class OrderMsgHandler { 
public void handleMsg(Order order) { 
/**/ 
} 
} 
<jms:listener-container …> 
<jms:listener destination="order" 
ref="orderMsgHandler" method="handleMsg" /> 
</jms:listener-container>
@JmsListener 
After (Spring 4.1~) 
@Component 
public class OrderMsgHandler { 
@JmsListener(destination = "order") 
public void handleMsg(Order order) { 
/**/ 
} 
} 
<jms:annotation-driven /> 
<jms:listener-container … />
JavaConfigの場合 
@Configuration 
@EnableJms 
public class AppConfig { 
@Bean 
JmsListenerContainerFactory jmsListenerContainerFactory() { 
DefaultJmsListenerContainerFactory factory = 
new DefaultJmsListenerContainerFactory(); 
factory.setConnectionFactory(connectionFactory()); 
factory.setDestinationResolver(destinationResolver()); 
factory.setConcurrency("3-10"); 
return factory; 
} 
// … 
}
JavaConfigの場合 
@Configuration 
@EnableJms 
public class AppConfig { 
@Bean 
JmsListenerContainerFactory jmsListenerContainerFactory() { 
Spring Bootなら設定不要 
DefaultJmsListenerContainerFactory factory = 
new DefaultJmsListenerContainerFactory(); 
factory.setConnectionFactory(connectionFactory()); 
factory.setDestinationResolver(destinationResolver()); 
factory.setConcurrency("3-10"); 
return factory; 
} 
// … 
}
柔軟なメソッドシグニチャ対応 
@JmsListener(destination = "order") 
public void handleMsg(Order order) {} 
! 
@JmsListener(destination = “order") 
public void handleMsg(Session session, TextMessage message) {} 
! 
@JmsListener(destination = "order") 
public void handleMsg(@Valid Order order) {} 
! 
@JmsListener(destination = "order") 
public void handleMsg(Order order, @Header String orderType) {} 
! 
@JmsListener(destination = “order") 
@SendTo("orderStatus") 
public OrderStatus handleMsg(Order order) {}
ちなみにJMS 2.0の場合 
@MessageDriven(…) 
public class OrderMsgHandler 
implements MessageListener { 
@Override 
public void onMessage(Message message) { 
try { 
Order order = message.getBody(Order.class); 
// … 
} catch (JMSException e) {/**/} 
} 
}
ちなみにJMS 2.0の場合 
@MessageDriven(…) 
public class OrderMsgHandler 
implements MessageListener { 
@Inject 
JmsContext jmsContext; 
@Override 
public void onMessage(Message message) { 
try { 
Order order = message.getBody(Order.class); 
// … 
OrderType orderType = …; 
jmsContext.createProducer() 
.setJMSCorrelationID(message.getJMSMessageID()) 
.send(message.getJMSReplyTo(), orderType); 
} catch (JMSException e) {/**/} 
} 
}
spring-messagingサポート 
• spring-messagingはSpring 4.0から導入さ 
れたメッセージング抽象化プロジェクト 
org.springframework.messaging.Message<T> 
T getPayload() 
MessageHeaders getHeaders() 
@JmsListener(destination = "order") 
@SendTo(“orderStatus") 
public Message<OrderStatus> 
handleMsg(Message<Order> order)
spring-messaging 
spring-messaging 
STOMP 
TCP 
JMS 
SQS 
SNS 
WebSocket 
Reactor 
AWS SDK for Java 
4.0~ 
4.1~ 
Spring 
Cloud 
for 
AWS
spring-messaging 
spring-messaging 
STOMP 
Spring TCP 
Integrationでも 
使JMS 
用されている 
SQS 
SNS 
WebSocket 
Reactor 
AWS SDK for Java 
4.0~ 
4.1~ 
Spring 
Cloud 
for 
AWS
JmsMessagingTemplate 
• spring-messagingのインタフェースを実装 
• MessagingSendingOperations 
• MessagingRecevingOperations 
• MessagingRequestReplyOperations 
• もともとあるJmsTemplateをラップ 
• 例外変換サポート
JmsMessagingTemplate 
Message<Order> msg = MessageBuilder 
.withPayload(order) 
.setHeader("orderType", "sell") 
.build(); 
! 
messageTemplate.send("order", msg);
JCache(JSR-107)サポート 
• JCacheによる宣言的キャッ 
シュに対応 
• JCacheに対応したキャッシュ 
製品を透過的に扱える
Springのキャッシュサポート 
Before (Spring 3.1~) 
org.springframework.cache.annotation.* 
public class BookService { 
@Cacheable("books") 
public Book findById(String id) {/**/} 
@Cacheable(value="books",key= 
"T(com.example.BookIdResolver).resolve(#isbn)") 
public Book findByIsbn(ISBN isbn) {/**/} 
@CachePut(value="books",key="#book.id") 
public void update(Book book) {/**/} 
@CacheEvict("books") 
public void delete(String id) {/**/} 
}
Springのキャッシュサポート 
Before (Spring 4.1の改善) 
@CacheConfig("books") 
public class BookService { 
@Cacheable 
public Book findById(String id) {/**/} 
@Cacheable(key="T(com.example.BookIdResolver).resolve(#isbn)") 
public Book findByIsbn(ISBN isbn) {/**/} 
@CachePut(key="#book.id") 
public void update(Book book) {/**/} 
@CacheEvict 
public void delete(String id) {/**/} 
} 
org.springframework.cache.annotation.*
JCacheサポート 
After 
javax.cache.annotation.* 
@CacheDefaults(cacheName = "books") 
public class BookService { 
@CacheResult 
public Book findById(String id) {/**/} 
@CacheResult(cacheKeyGenerator = IsbnCacheKeyGenerator.class) 
public Book findByIsbn(ISBN isbn) {/**/} 
@CachePut 
public void update(String id, 
@CacheValue Book book) {/**/} 
@CacheRemove 
public void delete(String id) {/**/}}
Configuration 
@Configuration 
@EnableCaching 
public class AppConfig { 
@Value("classpath:my-ehcache.xml") 
Resource ehCacheConfig; 
@Bean 
CacheManager cacheManager() { 
return new EhCacheManager(EhCacheManagerUtils 
.buildCacheManager(ehCacheConfig)); 
} 
// … 
} 
Before
Configuration 
Before 
@Configuration 
@EnableCaching 
public class AppConfig { 
@Bean 
CacheManager cacheManager() { 
return new JCacheManager(); 
} 
// … 
}
Configuration 
Before 
@Configuration 
@EnableCaching 
public class AppConfig { 
@Bean 
CacheManager cacheManager() { 
javax.cache.CacheManager 
cacheManager = Caching.getCachingProvider() 
.getCacheManager(); 
// JCache standard configuration … 
return new JCacheManager(cacheManager); 
} 
}
Web機能の改善 
静的リソース制御の改善 
Controller引数のOptionalサポート 
Controllerの返値のListenableFutureサポート 
Jacksonの@JsonViewサポート 
JSONPサポート 
ResponseBodyAdvice追加 
新しいHttpMessageConverter追加 
EL関数 s:mvcUrl 追加 
ResponseEntityビルダーサポート 
GroovyMarkupTemplateサポート
静的リソースサポート < 4.1 
• 静的リソースをSpringのResouceクラ 
スで表現できるパスから提供 
• classpath, filesystem, servlet context 
• 基本的なHTTPキャッシュ機構 
• Expires, Cache-Control, Last- 
Modified
静的リソースサポート < 4.1 
<mvc:resources mapping="/resources/**" 
location="classpath:META-INF/resources/" 
cache-period="#{60 * 60}" /> 
OR 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/resources/**") 
.addResourceLocations("classpath:META-INF/resources/") 
.setCachePeriod(60 * 60); 
} 
}
残る課題 
• オプティマイゼーション(minify, 結合,など 
• 変換 (sass, less, gzipなど) 
• 効率的なHTTPキャッシング(versioning) 
• 開発・デバッグ時の再読み込み(F5)容易性
残る課題 
• オプティマイゼーション(minify, 結合,など 
変換 Ruby on Rails 
• (sass, のless, Asset gzipPipeline 
など) 
• 効率的のなよHTTPうなキャ機ッ能シがング欲(versioning) 
しい 
• 開発・デバッグ時の再読み込み(F5)容易性
残る課題 
• オプティマイゼーション(minify, 結合,など 
• 変換 (sass, だless, がgzip断など) 
る 
• 効率的なHTTPキャッシング(versioning) 
• 開発・デバッグ時の再読み込み(F5)容易性
最近のフロントエンド開発 
•結合や変換はGulpやGrunt 
を使ってビルド時に解決
残る課題 
やらない 
(ビルドツール任せ) 
• オプティマイゼーション(minify, 結合,など 
• 変換 (sass, less, gzipなど) 
• 効率的なHTTPキャッシング(versioning) 
• 開発・デバッグ時の再読み込み(F5)容易性 
(ランタイムで本当に必要な場所のみ) やる
2つのインタフェース追加 
•ResourceResolver 
•ResourceTransformer
ResourceResolver 
•リクエストのURLからサー 
バー上のリソースを解決する 
•リソースのパブリックな 
URLを返す
ResourceResolver 
•PathResourceResolver 
•普通に存在するファイルを探して解決(これまでと同じ 
挙動) 
•VersionResourceResolver 
•バージョン付きファイル名を解決。Cache Busting 
•GzipResourceResolver 
•"Accept-Encoding: gzip”でリクエストがきたら、.gz 
を探す 
•CachingResourceResolver 
• リソースをキャッシュする
設定方法 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new VersionResourceResolver() 
.addContentVersionStrategy("/**")); 
} 
}
設定方法 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new VersionResourceResolver() 
.addContentVersionStrategy("/**")); 
} 
} 
"/**"パターンに該当するリソースパス 
に対してコンテンツハッシュを使用し 
たバージョニングポリシーを設定
VersionStrategy 
• ContentVersionStrategy 
• ファイルコンテンツのmd5ハッシュ値をバージョンに使用 
する 
• 頻繁に変更する可能性のあるファイルのバージョンに有効 
• FixedVersionStrategy 
• プロパティファイルの値やGitのリビジョン等の固定値を 
バージョンに使用する 
• 3rdパーティライブラリファイルのバージョンに有効
設定方法 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/resources/**") 
.addResourceLocations("classpath:META-INF/resources/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new VersionResourceResolver() 
.addFixedVersionStrategy("v1", "/**/hoge*.js") 
.addContentVersionStrategy("/**")); 
} 
}
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter 
@Bean 
ResourceUrlEncodingFilter 
resourceUrlEncodingFilter() { 
return new ResourceUrlEncodingFilter(); 
} 
HttpResponseWrapperを実装して、 
HttpServletResponse#encodeURLで 
変換後のパスを返す
function foo() { 
return "Hello World!"; 
} 
src/main/resources/public/foo.js
function foo() { 
return "Hello World!"; 
} 
src/main/resources/public/foo.js 
Thymeleaf 
JSP 
<script th:src="@{/public/foo.js}"></script> 
<script src="<c:url value="/public/foo.js" / 
>" ></script>
function foo() { 
return "Hello World!"; 
} 
src/main/resources/public/foo.js 
Thymeleaf 
JSP 
<script th:src="@{/public/foo.js}"></script> 
<script src="<c:url value="/public/foo.js" / 
>" ></script> 
<script src="/public/foo-c2efac2672ad1ab3753ae1902c0af8d3. 
js"></ 
script>
function foo() { 
return "Hello World!"; 
} 
src/main/resources/public/foo.js 
Thymeleaf 
JSP 
<script th:src="@{/public/foo.js}"></script> 
<script src="<c:url value="/public/foo.js" / 
>" ></script> 
<script src="/public/foo-c2efac2672ad1ab3753ae1902c0af8d3. 
js"></ 
script> 
初回は200 OK 
2回目以降は304 Not Modified 
が返り、クライアントでキャッシュ
function foo() { 
return "Hello World2!"; 
} 
src/main/resources/public/foo.js 
Thymeleaf 
JSP 
<script th:src="@{/public/foo.js}"></script> 
<script src="<c:url value="/public/foo.js" / 
>" ></script> 
<script src="/public/foo-b17a959b58873484644b5ff7161b6475. 
js"></ 
script>
function foo() { 
return "Hello World2!"; 
} 
src/main/resources/public/foo.js 
ファイル内容が代わり、 
バージョン(ファイル名) 
Thymeleaf 
JSP 
<script th:src="@{/public/foo.js}"></script> 
<script src="<c:url value="/public/foo.js" / 
>" ></script> 
<script src="/public/foo-b17a959b58873484644b5ff7161b6475. 
js"></ 
script> 
が変わったので 
再度200 OKでキャッシュ破棄
function foo() { 
return "Hoge!"; 
} 
src/main/resources/public/hoge.js 
Thymeleaf 
<script th:src="@{/public/hoge.js}"></ 
script> 
JSP 
<script src="<c:url value="/public/ 
hoge.js" />" ></script> 
<script src="/public/v1/hoge.js"></script>
設定方法(続き) 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addFixedVersionStrategy("v1", "/**/hoge*.js") 
.addContentVersionStrategy("/**")); 
} 
}
設定方法(続き) 
ここをtrueにする 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addFixedVersionStrategy("v1", "/**/hoge*.js") 
.addContentVersionStrategy("/**")); 
} 
} 
と自動で 
CacheResolverも 
追加される
設定方法(続き) 
ここをtrueにする 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addFixedVersionStrategy("v1", "/**/hoge*.js") 
.addContentVersionStrategy("/**")); 
} 
} 
と自動で 
CacheResolverも 
追加される 
最後にPathResolver 
も自動で追加される
ResourceTransformer 
•CssLinkResourceTransformer 
•CSSコンテンツ中のパスを書き換える 
•AppCacheManifestResourceTransformer 
• HTML5のAppCache manifestファイル中のパ 
スを書き換える 
• manifestファイルのコメントにコンテンツの 
ハッシュ値を挿入する 
•CachingResourceTransformer 
•キャッシュ済みコンテンツを返す
設定方法 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addContentVersionStrategy("/**")) 
.addTransformer(new AppCacheManifestTransformer()); 
} 
}
設定方法 
ここをtrueにする 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addContentVersionStrategy("/**")) 
.addTransformer(new AppCacheManifestTransformer()); 
} 
} 
と自動で 
CacheTransformer 
も追加される
設定方法 
ここをtrueにする 
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry){ 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(true /* cacheするかどうか */) 
.addResolver(new GzipResourceResolver()) 
.addResolver(new VersionResourceResolver() 
.addContentVersionStrategy("/**")) 
.addTransformer(new AppCacheManifestTransformer()); 
} 
} 
と自動で 
CacheTransformer 
も追加される 
VersionResolverを 
登録すると 
CssLinkTransformer 
も自動で追加される
src/main/resources/public/app.css 
@import url('bar.css'); 
src/main/resources/public/bar.css 
strong {color : red;} 
Thymeleaf 
<link rel="stylesheet" 
th:href="@{/public/app.css}"/> 
JSP 
<link rel="stylesheet" 
href="<c:url value="/public/app.css" />" />
<link rel="stylesheet" href="/public/ 
app-76f48a0aee85c84475a90ce82c7e610c.css" />
<link rel="stylesheet" href="/public/ 
app-76f48a0aee85c84475a90ce82c7e610c.css" /> 
app-76f48a0aee85c84475a90ce82c7e610c.css 
@import url('bar-dc1a9a1dc7a9264c8db2e66898f4759a. 
css');
<link rel="stylesheet" href="/public/ 
app-76f48a0aee85c84475a90ce82c7e610c.css" /> 
app-76f48a0aee85c84475a90ce82c7e610c.css 
@import url('bar-dc1a9a1dc7a9264c8db2e66898f4759a. 
css'); 
CssLinkResourceTransformerによっ 
てcssの中のリンクもバージョン付き 
に変換される
@Configuration 
@EnableWebMvc 
public class WebConfig extends WebMvcConfigurerAdapter { 
@Autowired 
Environment env; 
@Override 
public void 
addResourceHandlers(ResourceHandlerRegistry registry){ 
boolean devMode = this.env.acceptsProfiles("dev"); 
boolean useResourceCache = !devMode; 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(useResourceCache) 
…; 
} 
}
@Configuration 
@EnableWebMvc 
profileでキャッシュするか 
public class WebConfig @Autowired 
どextends うかWebMvcConfigurerAdapter 切り替えると良い 
{ 
Environment env; 
@Override 
public void 
addResourceHandlers(ResourceHandlerRegistry registry){ 
boolean devMode = this.env.acceptsProfiles("dev"); 
boolean useResourceCache = !devMode; 
registry.addResourceHandler("/public/**") 
.addResourceLocations("classpath:/public/") 
.setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); 
.resourceChain(useResourceCache) 
…; 
} 
}
その他のURL取得方法・・・ 
JSP 
<%=((ResourceUrlProvider) request 
.getAttribute("org.springframework.web.servlet.resource.ResourceUrlProvider")) 
.getForLookupPath("/public/app.css")%>
XMLによる定義 
<mvc:resources mapping="/public/**" 
location="classpth:/public/" 
cache-period="#{60 * 60 * 24 * 365}"> 
<mvc:resource-chain> 
<mvc:resource-cache /> 
<mvc:resolvers> 
<mvc:version-resolver> 
<mvc:content-version-strategy patterns="/**"/> 
</mvc:version-resolver> 
</mvc:resolvers> 
</mvc:resource-chain> 
</mvc:resources>
XMLによる定義 
そろそろXML辛い・・・ 
<mvc:resources mapping="/public/**" 
location="classpth:/public/" 
cache-period="#{60 * 60 * 24 * 365}"> 
<mvc:resource-chain> 
<mvc:resource-cache /> 
<mvc:resolvers> 
<mvc:version-resolver> 
<mvc:content-version-strategy patterns="/**"/> 
</mvc:version-resolver> 
</mvc:resolvers> 
</mvc:resource-chain> 
</mvc:resources>
フルセットなAsset Pipelineが欲 
しい場合 
• http://wuic.github.io/
http://wuic.github.io/project.html#roadmap
ResourceResolverと 
VersionStrategyが提供されている 
@Autowired 
WuicFacade wiucFacade; 
! 
@Override 
public void addResourceHandlers(ResourceHandlerRegistry 
registry) { 
registry.addResourceHandler("/wuic/**") 
.resourceChain(true) 
.addResolver(new VersionResourceResolver() 
.addVersionStrategy(new WuicVersionStrategy(), 
"/**/*")) 
.addResolver(new WuicPathResourceResolver(wuicFacade)); 
}
Spring 4.1を始めましょう
まとめ 
• SpringOne 2gx 
• 参加してコネクションを作ろう 
• 来年はワシントン 
• Spring 4.1の新機能 
• Web機能の改善 
• JMS機能の改善 
• Cache機能の改善http://bit.ly/hajiboot

More Related Content

What's hot

Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要kuroiwa
 
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!Java女子部
 
Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Chihiro Ito
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceWataruOhno
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ UndertowについてYoshimasa Tanabe
 
[JavaDo] JAX-RS ハンズオン 第2部
[JavaDo] JAX-RS ハンズオン 第2部[JavaDo] JAX-RS ハンズオン 第2部
[JavaDo] JAX-RS ハンズオン 第2部haruki ueno
 
テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術Y Watanabe
 
WildFly Swarmではじめる「パーツとしてのJavaEE」
WildFly Swarmではじめる「パーツとしてのJavaEE」WildFly Swarmではじめる「パーツとしてのJavaEE」
WildFly Swarmではじめる「パーツとしてのJavaEE」Hiroaki NAKADA
 
Spring Security 4.1 の新機能
Spring Security 4.1 の新機能Spring Security 4.1 の新機能
Spring Security 4.1 の新機能正和 井岡
 
Spring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へSpring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へMasatoshi Fujino
 
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発Yoshitaka Kawashima
 
TDC20111031_Groovy_Geb
TDC20111031_Groovy_GebTDC20111031_Groovy_Geb
TDC20111031_Groovy_GebNobuhiro Sue
 
JavaScriptでWebDriverのテストコードを書きましょ
JavaScriptでWebDriverのテストコードを書きましょJavaScriptでWebDriverのテストコードを書きましょ
JavaScriptでWebDriverのテストコードを書きましょKohki Nakashima
 
Spring Integration 超入門
Spring Integration 超入門Spring Integration 超入門
Spring Integration 超入門Yasutaka Sugamura
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsYoshimasa Tanabe
 
Play!30分クッキング
Play!30分クッキングPlay!30分クッキング
Play!30分クッキングShinichi Kozake
 
React入門-JSONを取得して表示する
React入門-JSONを取得して表示するReact入門-JSONを取得して表示する
React入門-JSONを取得して表示するregret raym
 
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話JustSystems Corporation
 

What's hot (20)

Spring integration概要
Spring integration概要Spring integration概要
Spring integration概要
 
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
 
Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発Quarkus による超音速な Spring アプリケーション開発
Quarkus による超音速な Spring アプリケーション開発
 
Spring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web ServiceSpring Fest 2018 Spring Bootで作るRESTful Web Service
Spring Fest 2018 Spring Bootで作るRESTful Web Service
 
Spring と TDD
Spring と TDDSpring と TDD
Spring と TDD
 
Jenkins 2.0 (日本語)
Jenkins 2.0 (日本語)Jenkins 2.0 (日本語)
Jenkins 2.0 (日本語)
 
次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて次世代Webコンテナ Undertowについて
次世代Webコンテナ Undertowについて
 
[JavaDo] JAX-RS ハンズオン 第2部
[JavaDo] JAX-RS ハンズオン 第2部[JavaDo] JAX-RS ハンズオン 第2部
[JavaDo] JAX-RS ハンズオン 第2部
 
テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術テストゼロからイチに進むための戦略と戦術
テストゼロからイチに進むための戦略と戦術
 
WildFly Swarmではじめる「パーツとしてのJavaEE」
WildFly Swarmではじめる「パーツとしてのJavaEE」WildFly Swarmではじめる「パーツとしてのJavaEE」
WildFly Swarmではじめる「パーツとしてのJavaEE」
 
Spring Security 4.1 の新機能
Spring Security 4.1 の新機能Spring Security 4.1 の新機能
Spring Security 4.1 の新機能
 
Spring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へSpring BootでHello Worldのその先へ
Spring BootでHello Worldのその先へ
 
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発
 
TDC20111031_Groovy_Geb
TDC20111031_Groovy_GebTDC20111031_Groovy_Geb
TDC20111031_Groovy_Geb
 
JavaScriptでWebDriverのテストコードを書きましょ
JavaScriptでWebDriverのテストコードを書きましょJavaScriptでWebDriverのテストコードを書きましょ
JavaScriptでWebDriverのテストコードを書きましょ
 
Spring Integration 超入門
Spring Integration 超入門Spring Integration 超入門
Spring Integration 超入門
 
WildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE AppsWildFly Swarm - Rightsize Your Java EE Apps
WildFly Swarm - Rightsize Your Java EE Apps
 
Play!30分クッキング
Play!30分クッキングPlay!30分クッキング
Play!30分クッキング
 
React入門-JSONを取得して表示する
React入門-JSONを取得して表示するReact入門-JSONを取得して表示する
React入門-JSONを取得して表示する
 
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
Spring Boot の Web アプリケーションを Docker に載せて AWS ECS で動かしている話
 

Viewers also liked

Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Toshiaki Maki
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...Toshiaki Maki
 
Spring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcSpring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcToshiaki Maki
 
ビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streamingビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streamingchibochibo
 
WalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block DevicesWalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block Devicesuchan_nos
 
3000社の業務データ絞り込みを支える技術
3000社の業務データ絞り込みを支える技術3000社の業務データ絞り込みを支える技術
3000社の業務データ絞り込みを支える技術Ryo Mitoma
 
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ーTeppei Sato
 
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜Jumpei Miyata
 
あなたの開発チームには、チームワークがあふれていますか?
 あなたの開発チームには、チームワークがあふれていますか? あなたの開発チームには、チームワークがあふれていますか?
あなたの開発チームには、チームワークがあふれていますか?Yusuke Amano
 

Viewers also liked (10)

Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
Event Driven Microservices with Spring Cloud Stream #jjug_ccc #ccc_ab3
 
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...Data Microservices with Spring Cloud Stream, Task,  and Data Flow #jsug #spri...
Data Microservices with Spring Cloud Stream, Task, and Data Flow #jsug #spri...
 
Spring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbcSpring Bootキャンプ @関ジャバ #kanjava_sbc
Spring Bootキャンプ @関ジャバ #kanjava_sbc
 
ビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streamingビッグじゃなくても使えるSpark Streaming
ビッグじゃなくても使えるSpark Streaming
 
形態素解析
形態素解析形態素解析
形態素解析
 
WalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block DevicesWalB: Real-time and Incremental Backup System for Block Devices
WalB: Real-time and Incremental Backup System for Block Devices
 
3000社の業務データ絞り込みを支える技術
3000社の業務データ絞り込みを支える技術3000社の業務データ絞り込みを支える技術
3000社の業務データ絞り込みを支える技術
 
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
離れた場所でも最高のチームワークを実現する方法 ーサイボウズ開発チームのリモートワーク事例ー
 
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜
Jenkins 2.0 最新事情 〜Make Jenkins Great Again〜
 
あなたの開発チームには、チームワークがあふれていますか?
 あなたの開発チームには、チームワークがあふれていますか? あなたの開発チームには、チームワークがあふれていますか?
あなたの開発チームには、チームワークがあふれていますか?
 

Similar to SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug

Implementation patterns
Implementation patternsImplementation patterns
Implementation patternsTatsuya Maki
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for JavaTakuya Tsuchida
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)Fujio Kojima
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみたYuki Takei
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用Yatabe Terumasa
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略takezoe
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようずOda Shinsuke
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkToshiaki Maki
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門spring_raining
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとかyouku
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2DToshiyuki Ienaga
 
WordPressと外部APIとの連携
WordPressと外部APIとの連携WordPressと外部APIとの連携
WordPressと外部APIとの連携Hidekazu Ishikawa
 
G*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+BetamaxG*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+BetamaxNobuhiro Sue
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライMasanobu Sato
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」yoshiaki iwanaga
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 

Similar to SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug (20)

Implementation patterns
Implementation patternsImplementation patterns
Implementation patterns
 
Google App Engine for Java
Google App Engine for JavaGoogle App Engine for Java
Google App Engine for Java
 
Java EE8 Report
Java EE8 ReportJava EE8 Report
Java EE8 Report
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略Seasarプロジェクト徹底攻略
Seasarプロジェクト徹底攻略
 
Selenium webdriver使ってみようず
Selenium webdriver使ってみようずSelenium webdriver使ってみようず
Selenium webdriver使ってみようず
 
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframeworkSpring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
Spring Frameworkの今 (2013年版) #jjug_ccc #ccc_r17 #springframework
 
About Jobs
About JobsAbout Jobs
About Jobs
 
React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門React.jsでクライアントサイドなWebアプリ入門
React.jsでクライアントサイドなWebアプリ入門
 
ScaLa+Liftとか
ScaLa+LiftとかScaLa+Liftとか
ScaLa+Liftとか
 
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
Next2Dで始めるゲーム開発  - Game Development Starting with Next2DNext2Dで始めるゲーム開発  - Game Development Starting with Next2D
Next2Dで始めるゲーム開発 - Game Development Starting with Next2D
 
WordPressと外部APIとの連携
WordPressと外部APIとの連携WordPressと外部APIとの連携
WordPressと外部APIとの連携
 
ScalaMatsuri 2016
ScalaMatsuri 2016ScalaMatsuri 2016
ScalaMatsuri 2016
 
Rx java x retrofit
Rx java x retrofitRx java x retrofit
Rx java x retrofit
 
G*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+BetamaxG*workshop 2011/11/22 Geb+Betamax
G*workshop 2011/11/22 Geb+Betamax
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
 
第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」第三回ありえる社内勉強会 「いわががのLombok」
第三回ありえる社内勉強会 「いわががのLombok」
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 

More from Toshiaki Maki

From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugToshiaki Maki
 
Concourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoConcourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoToshiaki Maki
 
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tServerless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tToshiaki Maki
 
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Toshiaki Maki
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerToshiaki Maki
 
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpOpen Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpToshiaki Maki
 
Spring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugSpring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugToshiaki Maki
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Toshiaki Maki
 
BOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoBOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoToshiaki Maki
 
Why PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootWhy PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootToshiaki Maki
 
Zipkin Components #zipkin_jp
Zipkin Components #zipkin_jpZipkin Components #zipkin_jp
Zipkin Components #zipkin_jpToshiaki Maki
 
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07Toshiaki Maki
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoToshiaki Maki
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsugToshiaki Maki
 
Spring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugSpring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugToshiaki Maki
 
Managing your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIManaging your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIToshiaki Maki
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoShort Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoToshiaki Maki
 
今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_kToshiaki Maki
 
Team Support in Concourse CI 2.0 #concourse_tokyo
Team Support in Concourse CI 2.0 #concourse_tokyoTeam Support in Concourse CI 2.0 #concourse_tokyo
Team Support in Concourse CI 2.0 #concourse_tokyoToshiaki Maki
 

More from Toshiaki Maki (20)

From Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsugFrom Spring Boot 2.2 to Spring Boot 2.3 #jsug
From Spring Boot 2.2 to Spring Boot 2.3 #jsug
 
Concourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyoConcourse x Spinnaker #concourse_tokyo
Concourse x Spinnaker #concourse_tokyo
 
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1tServerless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
Serverless with Spring Cloud Function, Knative and riff #SpringOneTour #s1t
 
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
決済システムの内製化への旅 - SpringとPCFで作るクラウドネイティブなシステム開発 #jsug #sf_h1
 
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
Spring Boot Actuator 2.0 & Micrometer #jjug_ccc #ccc_a1
 
Spring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & MicrometerSpring Boot Actuator 2.0 & Micrometer
Spring Boot Actuator 2.0 & Micrometer
 
Open Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjpOpen Service Broker APIとKubernetes Service Catalog #k8sjp
Open Service Broker APIとKubernetes Service Catalog #k8sjp
 
Spring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsugSpring Cloud Function & Project riff #jsug
Spring Cloud Function & Project riff #jsug
 
Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1Introduction to Spring WebFlux #jsug #sf_a1
Introduction to Spring WebFlux #jsug #sf_a1
 
BOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyoBOSH / CF Deployment in modern ways #cf_tokyo
BOSH / CF Deployment in modern ways #cf_tokyo
 
Why PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring BootWhy PCF is the best platform for Spring Boot
Why PCF is the best platform for Spring Boot
 
Zipkin Components #zipkin_jp
Zipkin Components #zipkin_jpZipkin Components #zipkin_jp
Zipkin Components #zipkin_jp
 
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
マイクロサービスに必要な技術要素はすべてSpring Cloudにある #DO07
 
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyoSpring Framework 5.0による Reactive Web Application #JavaDayTokyo
Spring Framework 5.0による Reactive Web Application #JavaDayTokyo
 
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug実例で学ぶ、明日から使えるSpring Boot Tips #jsug
実例で学ぶ、明日から使えるSpring Boot Tips #jsug
 
Spring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjugSpring ❤️ Kotlin #jjug
Spring ❤️ Kotlin #jjug
 
Managing your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CIManaging your Docker image continuously with Concourse CI
Managing your Docker image continuously with Concourse CI
 
Short Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyoShort Lived Tasks in Cloud Foundry #cfdtokyo
Short Lived Tasks in Cloud Foundry #cfdtokyo
 
今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k今すぐ始めるCloud Foundry #hackt #hackt_k
今すぐ始めるCloud Foundry #hackt #hackt_k
 
Team Support in Concourse CI 2.0 #concourse_tokyo
Team Support in Concourse CI 2.0 #concourse_tokyoTeam Support in Concourse CI 2.0 #concourse_tokyo
Team Support in Concourse CI 2.0 #concourse_tokyo
 

Recently uploaded

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directoryosamut
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000Shota Ito
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdffurutsuka
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxAtomu Hidaka
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。iPride Co., Ltd.
 

Recently uploaded (9)

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
Amazon SES を勉強してみる その12024/04/12の勉強会で発表されたものです。
 
20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory20240412_HCCJP での Windows Server 2025 Active Directory
20240412_HCCJP での Windows Server 2025 Active Directory
 
PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000PHP-Conference-Odawara-2024-04-000000000
PHP-Conference-Odawara-2024-04-000000000
 
UPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdfUPWARD_share_company_information_20240415.pdf
UPWARD_share_company_information_20240415.pdf
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptxIoT in the era of generative AI, Thanks IoT ALGYAN.pptx
IoT in the era of generative AI, Thanks IoT ALGYAN.pptx
 
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
新人研修のまとめ       2024/04/12の勉強会で発表されたものです。新人研修のまとめ       2024/04/12の勉強会で発表されたものです。
新人研修のまとめ 2024/04/12の勉強会で発表されたものです。
 

SpringOne 2GX 2014 参加報告 & Spring 4.1について #jsug

  • 1. SpringOne 2GX 2014 参加報告 & Spring 4.1について JSUG勉強会 #jsug 2014-12-11 Toshiaki Maki (@making)
  • 2. 自己紹介 • @making • http://blog.ik.am • 公私ともにSpringヘービーユーザー • 日本Javaユーザーグループ幹事
  • 4. 今日のコンテンツ • SpringOne 2gx 2014の様子 (5分) • Spring 4.1の新機能紹介 (45分)
  • 7. SpringOne 2gx 2014 • 2014/09/09~11 • ダラス
  • 8. SpringOne 2gx 2014 • 5つのトラック約120セッション • Core Spring • Data & Integration •Web & JavaScript • Applied Spring • Big Data • http://www.slideshare.net/SpringCentral/tag/springone2gx2014
  • 10. Food
  • 11. Beers
  • 17. 会場めっちゃ寒かった 景品のパーカー をもらうため会 場に散らばった 全てのバッジを 必死で探したw
  • 18. SpringOne 2gx 2015 • 来年はワシントンで開催予定
  • 21. Spring 4.1 • 2014年9月リリース • 現時点で4.1.3.RELEASE • メインストリームは4.2へ移行。 4.1はメンテナンスモードへ Spring Bootは1.2から対応
  • 22. Spring 4.1の主な新機能・改善 Web機能の改善 JMS機能の改善 Cache機能の改善 WebSocketメッセージング(STOMP)の改善 Test機能の改善 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/new-in-4.1.html
  • 23. Spring 4.1の主な新機能・改善 Web機能の改善 JMS機能の改善 Cache機能の改善 WebSocketメッセージング(STOMP)の改善 Test機能の改善 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/new-in-4.1.html
  • 24. Web機能の改善 静的リソース制御の改善 Controller引数のOptionalサポート Controllerの返値のListenableFutureサポート Jacksonの@JsonViewサポート JSONPサポート ResponseBodyAdvice追加 新しいHttpMessageConverter追加 EL関数 s:mvcUrl 追加 ResponseEntityビルダーサポート GroovyMarkupTemplateサポート
  • 25. Web機能の改善 静的リソース制御の改善 Controller引数のOptionalサポート Controllerの返値のListenableFutureサポート Jacksonの@JsonViewサポート JSONPサポート ResponseBodyAdvice追加 新しいHttpMessageConverter追加 EL関数 s:mvcUrl 追加 ResponseEntityビルダーサポート GroovyMarkupTemplateサポート
  • 28. Web機能の改善 静的リソース制御の改善 Controller引数のOptionalサポート Controllerの返値のListenableFutureサポート Jacksonの@JsonViewサポート JSONPサポート ResponseBodyAdvice追加 新しいHttpMessageConverter追加 EL関数 s:mvcUrl 追加 ResponseEntityビルダーサポート GroovyMarkupTemplateサポート
  • 29. Controller引数のOptionalサポート @RequestMapping(value = “/foo”) String foo(@RequestParam(required=false) String bar) { if (bar != null) { /* … */} } @RequestMapping(value = “/foo”) String foo(@RequestParam Optional<String> bar) { bar.map(value -> {/* … */}); } Before After
  • 30. WebじゃないけどOptinal対応 Before @Autowired(required=false) FooService fooService; After @Autowired Optional<FooService> fooService;
  • 31. Jacksonの@JsonViewサポート interface PublicView {}; class User { @PublicView private String username; private String password; // … } @RestController class UserController { @RequestMapping("/user") @JsonView(PublicView.class) User getUser() { return new User("demo", "password"); } }
  • 32. Jacksonの@JsonViewサポート interface PublicView {}; class User { @PublicView private String username; private String password; // … } @RestController class UserController { @RequestMapping("/user") @JsonView(PublicView.class) User getUser() { {"username":"demo"} return new User("demo", "password"); } }
  • 33. JSONPサポート @ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice { public JsonpAdvice() { super("callback"); } }
  • 34. JSONPサポート @RestController class UserController { @RequestMapping("/user") User getUser() { return new User("demo", "password"); } } GET /user?callback=foo foo({"username":"demo", "password":"password"})
  • 35. ResponseBodyAdvice • @ResponseBody/ResponseEntityメ ソッドへのコールバック • 2つの実装が組み込まれている • JsonViewResponseBodyAdvice • AbstractJsonpResponseBodyAdvice
  • 36. 新しいHttpMessageConverter追加 GsonHttpMessageConverter 軽量なJSONライブラリGSONを使用してHTTP経由で JSONをやりとり(通常はJacksonを使用する) ProtobufHttpMessageConverter HTTP経由でGoogleのシリアライゼーションフォーマッ トProtocol Bufferをやりとり MappingJackson2XmlHttpMessageConverter Jackson XMLを使用してHTTP経由でXMLをやりとり(通 常はJAXBを使用する)
  • 37. 使い方 従来のXMLの場合 <mvc:annotation-driven> <mvc:message-converters> <bean class=“….GsonHttpMessageConverter” /> </mvc:message-converters> </mvc:annotation-driven> Spring Bootの場合 @Configuration class AppConfig { @Bean HttpMessageConverter gsonHttpMessageConverter() { return new GsonHttpMessageConverter(); } }
  • 38. ResponseEntityビルダーサポート Before public ResponseEntity<String> handle() { String body = "Hi!"; HttpHeaders headers = new HttpHeaders(); headers.setLocation(location); return new ResponseEntity(body, headers, HttpStatus.CREATED); } After public ResponseEntity<String> handle() { URI location = …; return ResponseEntity.created(location).body("Hi!"); }
  • 39. RequestEntityビルダーサポート Before HttpHeaders headers = new HttpHeaders(); headers.setAccept(MediaType.APPLICATION_JSON); HttpEntity entity = new HttpEntity("Hi!", headers); restTemplate.exchange(uri, HttpMethod.POST, entity, String.class); After restTemplate.exchange(RequestEntity.post(uri) .accept(MediaType.APPLICATION_JSON) .body(Hi!), String.class);
  • 40. EL関数 s:mvcUrl 追加 @Controller @RequestMapping("/hotels/{hotel}") public class BookingController { @RequestMapping("/bookings/{booking}") String getBooking(@PathVariable Long booking) {/*…*/} } Before <a href="${pageContext.request.contextPath}/hotels/ 21/42" /> After <a href="${s:mvcUrl('BC#getBooking').arg(0, 42).buildAndExpand(21)}" />
  • 41. URI逆引き static import MvcUriComponentsBuilder.*; UriComponents uriComponents = fromMethodCall( on(BookingController.class).getBooking(21) ).buildAndExpand(42); URI uri = uriComponents.encode().toUri(); OR UriComponents uriComponents = fromMappingName("BC#getBooking") .arg(0, 21) .buildAndExpand(42); URI uri = uriComponents.encode().toUri();
  • 44. @JmsListener Before (Spring 2~) @Component public class OrderMsgHandler { public void handleMsg(Order order) { /**/ } } <jms:listener-container …> <jms:listener destination="order" ref="orderMsgHandler" method="handleMsg" /> </jms:listener-container>
  • 45. @JmsListener After (Spring 4.1~) @Component public class OrderMsgHandler { @JmsListener(destination = "order") public void handleMsg(Order order) { /**/ } } <jms:annotation-driven /> <jms:listener-container … />
  • 46. JavaConfigの場合 @Configuration @EnableJms public class AppConfig { @Bean JmsListenerContainerFactory jmsListenerContainerFactory() { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setDestinationResolver(destinationResolver()); factory.setConcurrency("3-10"); return factory; } // … }
  • 47. JavaConfigの場合 @Configuration @EnableJms public class AppConfig { @Bean JmsListenerContainerFactory jmsListenerContainerFactory() { Spring Bootなら設定不要 DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setDestinationResolver(destinationResolver()); factory.setConcurrency("3-10"); return factory; } // … }
  • 48. 柔軟なメソッドシグニチャ対応 @JmsListener(destination = "order") public void handleMsg(Order order) {} ! @JmsListener(destination = “order") public void handleMsg(Session session, TextMessage message) {} ! @JmsListener(destination = "order") public void handleMsg(@Valid Order order) {} ! @JmsListener(destination = "order") public void handleMsg(Order order, @Header String orderType) {} ! @JmsListener(destination = “order") @SendTo("orderStatus") public OrderStatus handleMsg(Order order) {}
  • 49. ちなみにJMS 2.0の場合 @MessageDriven(…) public class OrderMsgHandler implements MessageListener { @Override public void onMessage(Message message) { try { Order order = message.getBody(Order.class); // … } catch (JMSException e) {/**/} } }
  • 50. ちなみにJMS 2.0の場合 @MessageDriven(…) public class OrderMsgHandler implements MessageListener { @Inject JmsContext jmsContext; @Override public void onMessage(Message message) { try { Order order = message.getBody(Order.class); // … OrderType orderType = …; jmsContext.createProducer() .setJMSCorrelationID(message.getJMSMessageID()) .send(message.getJMSReplyTo(), orderType); } catch (JMSException e) {/**/} } }
  • 51. spring-messagingサポート • spring-messagingはSpring 4.0から導入さ れたメッセージング抽象化プロジェクト org.springframework.messaging.Message<T> T getPayload() MessageHeaders getHeaders() @JmsListener(destination = "order") @SendTo(“orderStatus") public Message<OrderStatus> handleMsg(Message<Order> order)
  • 52. spring-messaging spring-messaging STOMP TCP JMS SQS SNS WebSocket Reactor AWS SDK for Java 4.0~ 4.1~ Spring Cloud for AWS
  • 53. spring-messaging spring-messaging STOMP Spring TCP Integrationでも 使JMS 用されている SQS SNS WebSocket Reactor AWS SDK for Java 4.0~ 4.1~ Spring Cloud for AWS
  • 54. JmsMessagingTemplate • spring-messagingのインタフェースを実装 • MessagingSendingOperations • MessagingRecevingOperations • MessagingRequestReplyOperations • もともとあるJmsTemplateをラップ • 例外変換サポート
  • 55. JmsMessagingTemplate Message<Order> msg = MessageBuilder .withPayload(order) .setHeader("orderType", "sell") .build(); ! messageTemplate.send("order", msg);
  • 56. JCache(JSR-107)サポート • JCacheによる宣言的キャッ シュに対応 • JCacheに対応したキャッシュ 製品を透過的に扱える
  • 57. Springのキャッシュサポート Before (Spring 3.1~) org.springframework.cache.annotation.* public class BookService { @Cacheable("books") public Book findById(String id) {/**/} @Cacheable(value="books",key= "T(com.example.BookIdResolver).resolve(#isbn)") public Book findByIsbn(ISBN isbn) {/**/} @CachePut(value="books",key="#book.id") public void update(Book book) {/**/} @CacheEvict("books") public void delete(String id) {/**/} }
  • 58. Springのキャッシュサポート Before (Spring 4.1の改善) @CacheConfig("books") public class BookService { @Cacheable public Book findById(String id) {/**/} @Cacheable(key="T(com.example.BookIdResolver).resolve(#isbn)") public Book findByIsbn(ISBN isbn) {/**/} @CachePut(key="#book.id") public void update(Book book) {/**/} @CacheEvict public void delete(String id) {/**/} } org.springframework.cache.annotation.*
  • 59. JCacheサポート After javax.cache.annotation.* @CacheDefaults(cacheName = "books") public class BookService { @CacheResult public Book findById(String id) {/**/} @CacheResult(cacheKeyGenerator = IsbnCacheKeyGenerator.class) public Book findByIsbn(ISBN isbn) {/**/} @CachePut public void update(String id, @CacheValue Book book) {/**/} @CacheRemove public void delete(String id) {/**/}}
  • 60. Configuration @Configuration @EnableCaching public class AppConfig { @Value("classpath:my-ehcache.xml") Resource ehCacheConfig; @Bean CacheManager cacheManager() { return new EhCacheManager(EhCacheManagerUtils .buildCacheManager(ehCacheConfig)); } // … } Before
  • 61. Configuration Before @Configuration @EnableCaching public class AppConfig { @Bean CacheManager cacheManager() { return new JCacheManager(); } // … }
  • 62. Configuration Before @Configuration @EnableCaching public class AppConfig { @Bean CacheManager cacheManager() { javax.cache.CacheManager cacheManager = Caching.getCachingProvider() .getCacheManager(); // JCache standard configuration … return new JCacheManager(cacheManager); } }
  • 63. Web機能の改善 静的リソース制御の改善 Controller引数のOptionalサポート Controllerの返値のListenableFutureサポート Jacksonの@JsonViewサポート JSONPサポート ResponseBodyAdvice追加 新しいHttpMessageConverter追加 EL関数 s:mvcUrl 追加 ResponseEntityビルダーサポート GroovyMarkupTemplateサポート
  • 64. 静的リソースサポート < 4.1 • 静的リソースをSpringのResouceクラ スで表現できるパスから提供 • classpath, filesystem, servlet context • 基本的なHTTPキャッシュ機構 • Expires, Cache-Control, Last- Modified
  • 65. 静的リソースサポート < 4.1 <mvc:resources mapping="/resources/**" location="classpath:META-INF/resources/" cache-period="#{60 * 60}" /> OR @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/resources/**") .addResourceLocations("classpath:META-INF/resources/") .setCachePeriod(60 * 60); } }
  • 66. 残る課題 • オプティマイゼーション(minify, 結合,など • 変換 (sass, less, gzipなど) • 効率的なHTTPキャッシング(versioning) • 開発・デバッグ時の再読み込み(F5)容易性
  • 67. 残る課題 • オプティマイゼーション(minify, 結合,など 変換 Ruby on Rails • (sass, のless, Asset gzipPipeline など) • 効率的のなよHTTPうなキャ機ッ能シがング欲(versioning) しい • 開発・デバッグ時の再読み込み(F5)容易性
  • 68. 残る課題 • オプティマイゼーション(minify, 結合,など • 変換 (sass, だless, がgzip断など) る • 効率的なHTTPキャッシング(versioning) • 開発・デバッグ時の再読み込み(F5)容易性
  • 70. 残る課題 やらない (ビルドツール任せ) • オプティマイゼーション(minify, 結合,など • 変換 (sass, less, gzipなど) • 効率的なHTTPキャッシング(versioning) • 開発・デバッグ時の再読み込み(F5)容易性 (ランタイムで本当に必要な場所のみ) やる
  • 73. ResourceResolver •PathResourceResolver •普通に存在するファイルを探して解決(これまでと同じ 挙動) •VersionResourceResolver •バージョン付きファイル名を解決。Cache Busting •GzipResourceResolver •"Accept-Encoding: gzip”でリクエストがきたら、.gz を探す •CachingResourceResolver • リソースをキャッシュする
  • 74. 設定方法 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")); } }
  • 75. 設定方法 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")); } } "/**"パターンに該当するリソースパス に対してコンテンツハッシュを使用し たバージョニングポリシーを設定
  • 76. VersionStrategy • ContentVersionStrategy • ファイルコンテンツのmd5ハッシュ値をバージョンに使用 する • 頻繁に変更する可能性のあるファイルのバージョンに有効 • FixedVersionStrategy • プロパティファイルの値やGitのリビジョン等の固定値を バージョンに使用する • 3rdパーティライブラリファイルのバージョンに有効
  • 77. 設定方法 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/resources/**") .addResourceLocations("classpath:META-INF/resources/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new VersionResourceResolver() .addFixedVersionStrategy("v1", "/**/hoge*.js") .addContentVersionStrategy("/**")); } }
  • 78. org.springframework.web.servlet.resource.ResourceUrlEncodingFilter @Bean ResourceUrlEncodingFilter resourceUrlEncodingFilter() { return new ResourceUrlEncodingFilter(); } HttpResponseWrapperを実装して、 HttpServletResponse#encodeURLで 変換後のパスを返す
  • 79. function foo() { return "Hello World!"; } src/main/resources/public/foo.js
  • 80. function foo() { return "Hello World!"; } src/main/resources/public/foo.js Thymeleaf JSP <script th:src="@{/public/foo.js}"></script> <script src="<c:url value="/public/foo.js" / >" ></script>
  • 81. function foo() { return "Hello World!"; } src/main/resources/public/foo.js Thymeleaf JSP <script th:src="@{/public/foo.js}"></script> <script src="<c:url value="/public/foo.js" / >" ></script> <script src="/public/foo-c2efac2672ad1ab3753ae1902c0af8d3. js"></ script>
  • 82. function foo() { return "Hello World!"; } src/main/resources/public/foo.js Thymeleaf JSP <script th:src="@{/public/foo.js}"></script> <script src="<c:url value="/public/foo.js" / >" ></script> <script src="/public/foo-c2efac2672ad1ab3753ae1902c0af8d3. js"></ script> 初回は200 OK 2回目以降は304 Not Modified が返り、クライアントでキャッシュ
  • 83. function foo() { return "Hello World2!"; } src/main/resources/public/foo.js Thymeleaf JSP <script th:src="@{/public/foo.js}"></script> <script src="<c:url value="/public/foo.js" / >" ></script> <script src="/public/foo-b17a959b58873484644b5ff7161b6475. js"></ script>
  • 84. function foo() { return "Hello World2!"; } src/main/resources/public/foo.js ファイル内容が代わり、 バージョン(ファイル名) Thymeleaf JSP <script th:src="@{/public/foo.js}"></script> <script src="<c:url value="/public/foo.js" / >" ></script> <script src="/public/foo-b17a959b58873484644b5ff7161b6475. js"></ script> が変わったので 再度200 OKでキャッシュ破棄
  • 85. function foo() { return "Hoge!"; } src/main/resources/public/hoge.js Thymeleaf <script th:src="@{/public/hoge.js}"></ script> JSP <script src="<c:url value="/public/ hoge.js" />" ></script> <script src="/public/v1/hoge.js"></script>
  • 86. 設定方法(続き) @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addFixedVersionStrategy("v1", "/**/hoge*.js") .addContentVersionStrategy("/**")); } }
  • 87. 設定方法(続き) ここをtrueにする @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addFixedVersionStrategy("v1", "/**/hoge*.js") .addContentVersionStrategy("/**")); } } と自動で CacheResolverも 追加される
  • 88. 設定方法(続き) ここをtrueにする @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addFixedVersionStrategy("v1", "/**/hoge*.js") .addContentVersionStrategy("/**")); } } と自動で CacheResolverも 追加される 最後にPathResolver も自動で追加される
  • 89. ResourceTransformer •CssLinkResourceTransformer •CSSコンテンツ中のパスを書き換える •AppCacheManifestResourceTransformer • HTML5のAppCache manifestファイル中のパ スを書き換える • manifestファイルのコメントにコンテンツの ハッシュ値を挿入する •CachingResourceTransformer •キャッシュ済みコンテンツを返す
  • 90. 設定方法 @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")) .addTransformer(new AppCacheManifestTransformer()); } }
  • 91. 設定方法 ここをtrueにする @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")) .addTransformer(new AppCacheManifestTransformer()); } } と自動で CacheTransformer も追加される
  • 92. 設定方法 ここをtrueにする @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(true /* cacheするかどうか */) .addResolver(new GzipResourceResolver()) .addResolver(new VersionResourceResolver() .addContentVersionStrategy("/**")) .addTransformer(new AppCacheManifestTransformer()); } } と自動で CacheTransformer も追加される VersionResolverを 登録すると CssLinkTransformer も自動で追加される
  • 93. src/main/resources/public/app.css @import url('bar.css'); src/main/resources/public/bar.css strong {color : red;} Thymeleaf <link rel="stylesheet" th:href="@{/public/app.css}"/> JSP <link rel="stylesheet" href="<c:url value="/public/app.css" />" />
  • 94. <link rel="stylesheet" href="/public/ app-76f48a0aee85c84475a90ce82c7e610c.css" />
  • 95. <link rel="stylesheet" href="/public/ app-76f48a0aee85c84475a90ce82c7e610c.css" /> app-76f48a0aee85c84475a90ce82c7e610c.css @import url('bar-dc1a9a1dc7a9264c8db2e66898f4759a. css');
  • 96. <link rel="stylesheet" href="/public/ app-76f48a0aee85c84475a90ce82c7e610c.css" /> app-76f48a0aee85c84475a90ce82c7e610c.css @import url('bar-dc1a9a1dc7a9264c8db2e66898f4759a. css'); CssLinkResourceTransformerによっ てcssの中のリンクもバージョン付き に変換される
  • 97. @Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Autowired Environment env; @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ boolean devMode = this.env.acceptsProfiles("dev"); boolean useResourceCache = !devMode; registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(useResourceCache) …; } }
  • 98. @Configuration @EnableWebMvc profileでキャッシュするか public class WebConfig @Autowired どextends うかWebMvcConfigurerAdapter 切り替えると良い { Environment env; @Override public void addResourceHandlers(ResourceHandlerRegistry registry){ boolean devMode = this.env.acceptsProfiles("dev"); boolean useResourceCache = !devMode; registry.addResourceHandler("/public/**") .addResourceLocations("classpath:/public/") .setCachePeriod(60 * 60 * 24 * 365 /* 1年 */); .resourceChain(useResourceCache) …; } }
  • 99. その他のURL取得方法・・・ JSP <%=((ResourceUrlProvider) request .getAttribute("org.springframework.web.servlet.resource.ResourceUrlProvider")) .getForLookupPath("/public/app.css")%>
  • 100. XMLによる定義 <mvc:resources mapping="/public/**" location="classpth:/public/" cache-period="#{60 * 60 * 24 * 365}"> <mvc:resource-chain> <mvc:resource-cache /> <mvc:resolvers> <mvc:version-resolver> <mvc:content-version-strategy patterns="/**"/> </mvc:version-resolver> </mvc:resolvers> </mvc:resource-chain> </mvc:resources>
  • 101. XMLによる定義 そろそろXML辛い・・・ <mvc:resources mapping="/public/**" location="classpth:/public/" cache-period="#{60 * 60 * 24 * 365}"> <mvc:resource-chain> <mvc:resource-cache /> <mvc:resolvers> <mvc:version-resolver> <mvc:content-version-strategy patterns="/**"/> </mvc:version-resolver> </mvc:resolvers> </mvc:resource-chain> </mvc:resources>
  • 104. ResourceResolverと VersionStrategyが提供されている @Autowired WuicFacade wiucFacade; ! @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/wuic/**") .resourceChain(true) .addResolver(new VersionResourceResolver() .addVersionStrategy(new WuicVersionStrategy(), "/**/*")) .addResolver(new WuicPathResourceResolver(wuicFacade)); }
  • 106. まとめ • SpringOne 2gx • 参加してコネクションを作ろう • 来年はワシントン • Spring 4.1の新機能 • Web機能の改善 • JMS機能の改善 • Cache機能の改善http://bit.ly/hajiboot