Spring Framework 4.0과 4.1의 주요 업데이트 내용을 정리했습니다. 그리고, Spring I/O 2015 | The conference 에서 공개된 4.2의 소식들을 모아보았습니다. :)
ps. 제가 웬만하면 자료는 한글로 바꾸는 편인데... 이번에는 시간이 너무 부족해서 대부분 영어를 그대로 사용했네요. 다음에 기회가 되면 한글화시키는걸로...
10. 2013년 1월 16일 - Next Stop: Spring Framework 4.0
코어 프레임워크의 다음 버전이 4.0이 될것이라는 기쁜소식을 전합니다.
3.2 버전은 3.x 라인의 마지막 버전이 될것입니다.
3.x 버전에서는 JAVA 7, Servlet 3.0의 지원 및 자바 코드 기반 설정, REST에 초점을 두었습니다.
4.0은 엔터프라이즈 통합에 중심을 두고 개발이 진행될것입니다.
2013년 말에 릴리즈를 될것이며, 4월에 첫번째 마일스톤을 공개할 예정입니다.
“
46. ListPlayer players = playerRepository.findAll();
Collections.sort(players,
new ComparatorPlayer() {
public int compare(Player p1, Player p2) {
return p1.getRank().compareTo(p2.getRank());
}
}
);
Lambda Expressions New Collection API|
요즘 함수형 프로그래밍이 대세라던데?
스칼라나 그루비는 고차함수를 지원한다더라!
자바야. 우리도 람다식 좀 쓰고 싶다!
무슨 할말이 이렇게 많니?
47. ListPlayer players = playerRepository.findAll();
Collections.sort(players,
new ComparatorPlayer() {
public int compare(Player p1, Player p2) {
return p1.getRank().compareTo(p2.getRank());
}
}
);
players.sort((p1, p2) - p1.getRank().compareTo(p2.getRank()));
Lambda Expressions New Collection API|
결국...
48. Easy database queries for Java 8|
String sql = SELECT * FROM Customer C WHERE C.Name = ? ;
PreparedStatement statement = conn.prepareStatement(sql);
statement.setString(1, Alice);
ResultSet rs = statement.executeQuery();
ListCustomer customers = new ArrayList();
while (rs.next()) {
// customers.add(..)
}
database.customerStream().where(
customer - customer.getName().equals(Alice));
JinQ
49. JSR-310(Date And Time API)|
// 1일 후 구하기
void shouldGetAfterOneDay() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(yyyy.MM.dd);
LocalDate theDay = IsoChronology.INSTANCE.date(2015, 5, 26);
isTrue(formatter.format(theDay).equals(2015.05.26));
LocalDate nextDay = theDay.plusDays(1);
isTrue(formatter.format(nextDay).equals(2015.05.27));
}
// 1시간 후 구하기
void shouldGetAfterOneHour() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(yyyy.MM.dd HH:mm);
ZoneId seoul = ZoneId.of(Asia/Seoul);
ZonedDateTime theTime = ZonedDateTime.of(2015, 5, 26, 17, 0, 0, 0, seoul);
isTrue(theTime.format(formatter).equals(2015.05.26 17:00));
ZonedDateTime after1Hour = theTime.plusHours(1);
isTrue(after1Hour.format(formatter).equals(2015.05.26 18:00));
}
// 요일 확인하기
void shouldGetDayOfWeek() {
LocalDate theDay = LocalDate.of(2015, 5, 26);
DayOfWeek dayOfWeek = theDay.getDayOfWeek();
isTrue(dayOfWeek.equals(DayOfWeek.TUESDAY));
}
108. Java API for WebSocket (JSR-356)|
JSR 356: Java API for WebSocket
✓ HTML5 표준
✓ API: W3C / 프로토콜: IETF
✓ 웹 소켓 프로토콜 사용
✓ 양방향 통신
✓ Tomcat 7.0.47+ and 8.0
✓ Jetty 9.0 and 9.1
✓ WildFly 8.0 (JBoss Application Server)
✓ GlassFish 4.0
109. 2013년 1월 16일 - Next Stop: Spring Framework 4.0
2013년 12월 12일 - 4.0 Release
✓ First-class
1113. Spring Core|
Annotated JMS Endpoints
@JmsListener(destination=order)
public OrderStatus processOrder(Sort.Order order) {
// do something
}
@JmsListener(id=orderListener, containerFactory=“myJmsFactory
, destination=order, selector=type='sell')
@SendTo(orderStatus)
public OrderStatus processOrder(Sort.Order order, @Header String type) {
// do something
}
Annotated Event Listeners [4.2]
@EventListener
public void processEvent(String payload) {
// do something
}
@EventListener(condition=#payload.startsWith('OK'))
public void processEvent(String payload) {
// do something
}
1114. Spring Core|
JCache (JSR-107) Support
import javax.cache.annotation.*;
@CacheDefaults(cacheName=orders)
public class OrderRepository {
@CacheResult
public Order findById(String id) {
}
@CachePut
public void updateOrder(String id, @CacheValue Order book) {
}
@CacheRemove
public void delete(String id) {
}
}
1115. Spring Web|
handling static web resources
class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler(/**)
.addResourceLocations(classpath:public/)
.resourceChain(true)
.addResolver(new GzipResourceResolver())
.addResolver(new VersionResourceResolver().addContentVersionStrategy(/**))
.addTransformer(new CssLinkResourceTransformer());
}
@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
}
/* JSP */
%@ taglib prefix=spring uri=http://www.springframework.org/tags%
link rel='stylesheet' type='text/css' href='spring:url value=/css/default.css/'
script src=spring:url value=/js/app.js//script
/css/default-c847040f6a5a67d9556811064e228477.css
1116. Spring Web|
Using AsyncRestTemplate
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
ListenableFutureResponseEntityRepository[] listenableFuture
= asyncRestTemplate.getForEntity(GITHUB_API, Repository[].class, uriVariables);
reposForEntity.addCallback(response - {
// 성공
}, thrown - {
// 실패
});
intercepting @ResponseBody and ResponseEntity handlers
@ControllerAdvice
class JsonpResponseBodyAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpResponseBodyAdvice() {
super(callback);
}
}
ResponseBodyAdviceT
interface
http://springcamp.io/api/sessions?callback=renderSessions
1117. Spring Web|
Stomp on WebSocket
@Controller
public class StompController {
@SubscribeMapping(/positions)
public ListPortfolioPosition getPortfolios(Principal user) {
// do something
}
@MessageMapping(/trade)
public void executeTrade(Trade trade, Principal user) {
// do something
}
}
HTTP Streaming - Server-Sent Events [4.2]
@RequestMapping
public SseEmitter handlerSSE() {
SseEmitter emitter = new SseEmitter();
return emitter;
}
// Later from some other thread
emitter.send(new Event(noti.newMail), data));
emitter.send(new Event(noti.update), data));
emitter.complete();
1118. Spring Test|
@ActiveProfiles – Declarative
@ContextConfiguration
@ActiveProfiles(dev)
public class IntegrationTests {
// ...
}
Test Property Sources
@ContextConfiguration
@TestPropertySource(
locations = { /test.properties },
properties = { database: h2, port: 4242 }
)
public class IntegrationTests {
// ...
}
1119. Spring Test|
Executing SQL per Test Method
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@Sql({ schema1.sql, data1.sql })
public class SqlScriptsTests {
@Test
public void classLevelScripts() { /* ... */ }
@Test
@Sql({schema2.sql, data2.sql})
public void methodLevelScripts() { /* ... */ }
}
1120. Spring Test|
TestTransaction API
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@Transactional
public class TransactionalTests {
@Test
@Sql({ init-user-table.sql })
public void withinTransaction() {
// assert initial state in test database
assertNumUsers(2);
deleteFromTables(user);
// changes to the database will be committed
TestTransaction.flagForCommit();
TestTransaction.end();
assertFalse(TestTransaction.isActive());
assertNumUsers(0);
TestTransaction.start();
// perform other actions against the database that
// will be automatically rolled back after the test
// completes...
}
}