100
Spring 4 Ken Coenen, Dieter Hubau, Tim De Grande, Steve De Zitter, Serguei Storojenko, Andreas Evers

Spring 4 - A&BP CC

Embed Size (px)

Citation preview

Page 1: Spring 4 - A&BP CC

Spring 4Ken Coenen, Dieter Hubau, Tim De Grande, Steve De Zitter, Serguei Storojenko, Andreas Evers

Page 2: Spring 4 - A&BP CC

Agenda

Steve De Zitter

Java SDK & EE support

Tim De Grande

Spring Core

Serguei Storojenko

Spring WebMVC

Ken Coenen

WebSockets and Messaging

Dieter Hubau

Testing improvements

Andreas Evers

Spring Core

Page 3: Spring 4 - A&BP CC

Java 8 support

Page 4: Spring 4 - A&BP CC

Java 8 features in Spring 4/4.1

▪ Lambda expressions▪ Method references▪ JSR-310 Date/Time Support▪ Repeatable annotations▪ Parameter name discovery▪ Java.util.Optional

▪ Related new injection features▪ Ordering, @Priority, Generic types

Page 5: Spring 4 - A&BP CC

Java 8 lamda conventions

▪ Functional interfaces▪ Typically callback interfaces such as Runnable/Callable▪ Common functional interfaces in java.util.function

▪ Function, Predicate, Supplier▪ Used extensively in Java8 Streams Api

Page 6: Spring 4 - A&BP CC

Lambda conventions in Spring api’s

▪ TransactionTemplate with TransactionCallback▪ JdbcTemplate/JdbcOperations with PreparedStatementSetter▪ JdbcTemplate/JdbcOperations with RowMapper▪ TaskExecutor▪ ListenableFuture

Page 7: Spring 4 - A&BP CC

Lambdas JdbcOperations example

▪ PreparedStatementSetter and RowMapper pre Java 8List<Beer> beers = jdbcOperations.query(SELECT_BEER_BY_NAME_AND_ALCOHOL_PERCENTAGE, new PreparedStatementSetter() {

@Override public void setValues(PreparedStatement ps) throws SQLException{ ps.setString(1, "%" + name + "%"); ps.setBigDecimal(2, alcoholPercentage); } }, new RowMapper<Beer>() {

@Override public Beer mapRow(ResultSet rs, int rowNum) throws SQLException{ return new Beer(rs.getLong("id"), rs.getString("name"), rs.getString("description"), rs.getBigDecimal("alcoholPercentage"), rs.getTimestamp("modifiedTimestamp”)); }

});

Page 8: Spring 4 - A&BP CC

Lambdas JdbcOperations example

▪ PreparedStatementSetter and RowMapper with lambdas

List<Beer> beers = jdbcOperations.query(SELECT_BEER_BY_NAME_AND_ALCOHOL_PERCENTAGE,ps -> {

ps.setString(1, "%" + name + "%"); ps.setBigDecimal( 2, alcoholPercentage);},(rs, rowNum) -> new Beer(rs.getLong("id"),

rs.getString("name"),rs.getString("description"),rs.getBigDecimal( "alcoholPercentage”))

);

Page 9: Spring 4 - A&BP CC

Lambdas TaskExecutor example

▪ TaskExecutor (ThreadPoolTaskExecutor) pre Java 8

return threadPoolTaskExecutor.submitListenable( new Callable<List<Beer>>() {@Overridepublic List<Beer> call() throws Exception {

return beerRepository.getAllBeers();}

});

▪ TaskExecutor with lambdas

return threadPoolTaskExecutor.submitListenable( () -> beerRepository.getAllBeers());

Page 10: Spring 4 - A&BP CC

ListenableFuture example

▪ ListenableFuture pre Java 8 with ListenableFutureCallback

ListenableFuture<List<Beer>> future = taskExecutorService.getBeersAsyncUsingTaskExecutor();

future.addCallback( new ListenableFutureCallback<List<Beer>>() {@Overridepublic void onFailure(Throwable throwable) {

//Handle Failure}

@Overridepublic void onSuccess(List<Beer> beers) {

//Handle success}

});

Page 11: Spring 4 - A&BP CC

ListenableFuture example

▪ ListenableFuture pre Java 8 with success and failure callback

ListenableFuture<List<Beer>> future = taskExecutorService.getBeersAsyncUsingTaskExecutor();

future.addCallback( new SuccessCallback<List<Beer>>() {@Overridepublic void onSuccess(List<Beer> beers) {

//Handle success}

}, new FailureCallback() {@Overridepublic void onFailure(Throwable throwable) {

//Handle Failure}

});

Page 12: Spring 4 - A&BP CC

Lambdas ListenableFuture examples

▪ ListenableFuture with Lambdas

ListenableFuture<List<Beer>> listenableFuture = taskExecutorService.getBeersAsyncUsingAnnotationsAndListenableFuture();

listenableFuture.addCallback((beers) -> {beers.stream().forEach(System. out::println);

},(throwable) -> {

//Handle failure}

);

Page 13: Spring 4 - A&BP CC

Method references

▪ PreparedStatementSetter and RowMapper method reference example

List<Beer> beers = jdbcOperations.query(SELECT_BEER_BY_NAME_AND_ALCOHOL_PERCENTAGE,ps -> {

ps.setString(1, "%" + name + "%"); ps.setBigDecimal( 2, alcoholPercentage);

},this::mapRow

);

Page 14: Spring 4 - A&BP CC

JSR-310 Date/Time Api

▪ Support for Java8 LocalDate, LocalDateTime, …▪ @DateTimeFormat annotation is also applicable to Java8 Date/Time

types.▪ Bind String to JSR-310 Date/Time objects▪ Render JSR-310 objects to Strings

Page 15: Spring 4 - A&BP CC

JSR-310 Date/Time Api support example

▪ Mapping incoming @PathVariable to LocalDateTime

@RequestMapping(value = "/modified/{modifiedDate}",method = RequestMethod.GET)public List<Beer> getBeersModifiedAfterDate(

@PathVariable @DateTimeFormat(pattern="ddMMyyyyHHmm”)LocalDateTime modifiedDate){

return beerRepository.getBeersLastModifiedTimestampGreaterThan(Timestamp.valueOf(modifiedDate));

}

▪ /modified/110320151930

Page 16: Spring 4 - A&BP CC

JSR-310 Date/Time Api support example

▪ Domain object

public class Beer {private Long id;private String name;private String description;private BigDecimal alcoholPercentage;

// @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)private LocalDate since;

@DateTimeFormat(pattern = "ddMMyyyyHHmm")private LocalDateTime modifiedTimestamp;

Page 17: Spring 4 - A&BP CC

Rendering out the LocalDateTime property

▪ Jsp SnippetBeer modified timestamp: <form:input path="modifiedTimestamp" />

▪ Renders:

Page 18: Spring 4 - A&BP CC

Repeatable annotations

▪ @Scheduled▪ @PropertySource▪ …

Page 19: Spring 4 - A&BP CC

@PropertySource

▪ Java 8 Repeatable annotations@Configuration@PropertySource("classpath:/someProperties.properties")@PropertySource("classpath:/someProperties2.properties")public class SpringConfiguration {

▪ Pre-java8@Configuration@PropertySources(value = { @PropertySource("classpath:/someProperties.properties"), @PropertySource("classpath:/someProperties2.properties")})public class SpringConfiguration {

Page 20: Spring 4 - A&BP CC

@Scheduled

▪ Java 8 Repeatable annotations@Scheduled(cron = "0 0 12 * * ?"),@Scheduled(cron = "0 0 18 * * ?")public void scheduledTask() {

System.out.println(message + LocalDateTime.now());}

▪ Pre Java-8@Schedules({ @Scheduled(cron = "0 0 12 * * ?"), @Scheduled(cron = "0 0 18 * * ?")})public void scheduledTask() {

System.out.println(message + LocalDateTime.now());}

Page 21: Spring 4 - A&BP CC

Spring 4 Parameter discovery

▪ As of Spring 4.0 aware of Java8’s parameter reflection▪ Parameter names now available in Spring through common Java8

reflection methods.▪ Java8

▪ ‘-parameters’ compiler flag▪ Java 6 and 7: via asm

▪ ‘-debug’ compiler flag

Page 22: Spring 4 - A&BP CC

Spring 4 parameter discovery

▪ Without parameter discovery (no –debug or –parameters compilation flag)

@RequestMapping(value = "/{id}", method = RequestMethod. GET)public Beer getBeerById( @PathVariable("id") Long id) {

return beerRepository.getBeerById(id);}

▪ With Parameter discovery

@RequestMapping(value = "/{id}", method = RequestMethod. GET)public Beer getBeerById( @PathVariable Long id) {

return beerRepository.getBeerById(id);}

Page 23: Spring 4 - A&BP CC

Spring data custom query parameter discovery

▪ Custom query in Spring data JPA without parameter name discovery

▪ Custom query in Spring data JPA with parameter name discovery

Page 24: Spring 4 - A&BP CC

Java 8 Optional

▪ Java.util.Optional as method parameter type with annotations that have required attribute

▪ @RequestParam▪ @RequestHeader▪ @MatrixVariable▪ …

▪ Optional on Autowired dependencies

Page 25: Spring 4 - A&BP CC

Optional MVC Handler method parameters

▪ Using required=false@RequestMapping(value = "/{id}", method = RequestMethod. GET)public Beer getBeerById(

@PathVariable Long id,@RequestHeader(required=false) String country) {

if(country!=null)System.out.println(country);

return beerRepository.getBeerById(id);}

Page 26: Spring 4 - A&BP CC

Optional on MVC handler method parameter

▪ Usage of Optional on @RequestHeader parameter

@RequestMapping(value = "/{id}", method = RequestMethod. GET)public Beer getBeerById(

@PathVariable Long id,@RequestHeader Optional<String> country) {

country.ifPresent(System.out::println);

return beerRepository.getBeerById(id);}

Page 27: Spring 4 - A&BP CC

Optional on Injected dependencies

▪ Required=false on dependency@RestController@RequestMapping("/beers")public class BeerController {

@Autowired(required = false)private NotificationService notificationService;

▪ Using the dependency@RequestMapping(value = "/{id}", method = RequestMethod. GET)public Beer getBeerById(

@PathVariable Long id,@RequestHeader Optional<String> country) {

if(notificationService != null)notificationService.sendNotification("getBeerForId: " + id);

Page 28: Spring 4 - A&BP CC

Optional on Injected dependencies

▪ Optional dependency@RestController@RequestMapping("/beers")public class BeerController {

@Autowiredprivate Optional<NotificationService> notificationService;

▪ Using the dependency@RequestMapping(value = "/{id}", method = RequestMethod. GET)

public Beer getBeerById( @PathVariable Long id, @RequestHeader Optional<String> country) {

notificationService.ifPresent(service -> service.sendNotification( "getBeerForId: " + id)

);return beerRepository.getBeerById(id);

}

Page 29: Spring 4 - A&BP CC

Injection of Ordered Lists (Spring 4.0)

▪ Injection point or Ordered List@RestController @RequestMapping ("/beers")public class BeerController {

@Autowiredprivate List<MyService> services;

▪ MyService dependency with @Order(1)@Service @Order(1)public class MyServiceImpl implements MyService {

▪ MyService dependency with @Order(2)@Service @Order(2)public class MyOtherServiceImpl implements MyService {

Page 30: Spring 4 - A&BP CC

▪ Injection point for Ordered List@RestController @RequestMapping ("/beers")public class BeerController {

@Autowiredprivate List<MyService> services;

▪ MyService dependency with @Order(1)@Bean @Order(1)public MyService service1() {

return new MyServiceImpl();}

▪ MyService dependency with @Order(3)@Bean @Order(3)public MyService service2() {

return new MyOtherServiceImpl();}

@Order on @Bean methods (Spring 4.1)

Page 31: Spring 4 - A&BP CC

@javax.annotation.Priotity

▪ Injection point for Ordered List@RestController@RequestMapping("/beers")public class BeerController {

@Autowiredprivate List<MyService> services;

▪ MyService dependency with @Priority(1)@Service @Priority (1)public class MyServiceImpl implements MyService {

▪ MyService dependency with @Priority(2)@Service @Priority (2)public class MyOtherServiceImpl implements MyService {

Page 32: Spring 4 - A&BP CC

@Priority for primary candidate selection

▪ Inject 1 Bean with multiple @Priority beans@RestController @RequestMapping ("/beers")public class BeerController {

@Autowiredprivate MyService service; //Injects MyServiceImpl

▪ Inject 1 Bean with multiple @Order beans▪ Fails! Causes: org.springframework.beans.factory.

NoUniqueBeanDefinitionException▪ This can be solved however!

▪ By Electing 1 of the @Order beans with @Primary (Spring 3 annotation)@Service

@Order(1) @Primarypublic class MyServiceImpl implements MyService {

Page 33: Spring 4 - A&BP CC

@Qualifier for candidate selection

@Service @Qualifier ("myServiceImpl")public class MyServiceImpl implements MyService {

@Service @Qualifier("myOtherServiceImpl")public class MyOtherServiceImpl implements MyService {

@RestController @RequestMapping ("/beers")public class BeerController {

@Autowired @Qualifier ("myServiceImpl") private MyService service; //Injects MyServiceImpl

Page 34: Spring 4 - A&BP CC

Generic type for candidate selection (Spring 4.0)

@Servicepublic class BeerServiceImpl implements MyService<Beer> {

@Servicepublic class MyOtherServiceImpl implements MyService<OtherEntity> {

@RestController @RequestMapping ("/beers")public class BeerController {

@Autowired private MyService<Beer> service; //Injects BeerServiceImpl

Page 35: Spring 4 - A&BP CC

Sources and code

▪ Sources▪ http://spring.io/blog/2015/01/14/springone2gx-2014-replay-spring-framework-on-java-8▪ http://www.infoq.com/articles/spring-4-java-8▪ http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#new-in-4.0▪ http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#new-in-4.1

▪ Code▪ GitHub: https://github.com/Turbots/spring4_workshop▪ Maven module: spring4-java8-features

Page 36: Spring 4 - A&BP CC

Core Spring

Page 37: Spring 4 - A&BP CC

In the beginning there was… XML

Page 38: Spring 4 - A&BP CC

In the beginning there was… XML

▪ Spring 3 made it possible to get rid of XML configuration for Spring (mostly)

@Configuration

Page 39: Spring 4 - A&BP CC

But what about descriptions?

Page 40: Spring 4 - A&BP CC

Spring 4 adds the @Description annotation

But what about descriptions? (2)

Page 41: Spring 4 - A&BP CC

Spring 4 allows you to use all information to decide which beans to inject through @Conditional

Different strokes for different folks

Page 42: Spring 4 - A&BP CC

Different strokes for different folks (2)

Page 43: Spring 4 - A&BP CC

Conditions have access to:

Different strokes for different folks (3)

Annotated object Condition Context

AnnotationsMeta annotationsClass hierarchy...

Bean definition registryScopesBeans that are createdClassloaderEnvironmentResources...

Page 44: Spring 4 - A&BP CC

One step further

Page 45: Spring 4 - A&BP CC

In Spring 3▪ Only at the class level

▪ @Lazy components get created when they need to be injected.

Laziness

Page 46: Spring 4 - A&BP CC

Spring 4▪ Also at injection point

Laziness (2)

Page 47: Spring 4 - A&BP CC

Web Improvements

Page 48: Spring 4 - A&BP CC

48

General Web Improvements Spring 4.0

▪ Focused primarily on Servlet 3.0+ environments.▪ WebSocket support▪ New @RestController annotation▪ New AsyncRestTemplate class▪ Comprehensive time zone support

Page 49: Spring 4 - A&BP CC

49

Focus on Servlet 3.0 + environments

▪ Deployment to Servlet 2.5 servers remains an option

▪ Keep in mind: If you are using the Spring MVC Test Framework you will need to ensure that a Servlet 3.0 compatible JAR is in your test classpath.

▪ Main practical implication: web.xml is no longer needed (still supported, though)

Page 50: Spring 4 - A&BP CC

50

Interface WebApplicationInitializer

▪ WebApplicationInitializer must be used, if web.xml is not used

▪ DEMO

Page 51: Spring 4 - A&BP CC

51

@RestController annotation

▪ Before spring 4.0

▪ Spring 4.0

Page 52: Spring 4 - A&BP CC

52

AsyncRestTemplate

▪ Web applications often need to query external REST services these days. The very nature of HTTP and synchronous calls can lead up to challenges when scaling applications for those needs: multiple threads may be blocked, waiting for remote HTTP responses.

Page 53: Spring 4 - A&BP CC

53

AsyncRestTemplate (2)

▪ AsyncRestTemplate returns ListenableFuture wrapper instead of concrete results as RestTemplate does.

▪ ListenableFuture accepts completion callbacks

Page 54: Spring 4 - A&BP CC

54

ListenableFuture

▪ DEMO

Page 55: Spring 4 - A&BP CC

55

Comprehensive time zone support

▪ Before Spring 4.0

Page 56: Spring 4 - A&BP CC

56

Comprehensive time zone support (2)

▪ Spring 4.0: the new extension of LocaleContext provides TimeZone support

Page 57: Spring 4 - A&BP CC

57

Comprehensive time zone support (3)

▪ Spring 4.0: new LocalContextResolver

Page 58: Spring 4 - A&BP CC

58

Comprehensive time zone support (4)

▪ Out of box, there is a bunch of classes implementing LocalContextResolver interface.

▪ Some of them support setting default TimeZone▪ Some of them also support fall back to the server TimeZone

Page 59: Spring 4 - A&BP CC

59

Comprehensive time zone support (5)

▪ When available, the user’s TimeZone can be obtained using the RequestContext.getTimeZone() method.

▪ Time zone information will automatically be used by Date/Time Converter and Formatter objects registered with Spring’s ConversionService.

Page 60: Spring 4 - A&BP CC

60

Comprehensive time zone support (6)

QuestionHow to pass time zone info from the client to LocaleContext?

Page 61: Spring 4 - A&BP CC

61

Comprehensive time zone support (7)

▪ Old good Locale scenario:- Locale info passed as a request parameter (ex: user chooses language)- Out-of-box LocaleChangeInterceptor would intercept the request and

set the required Locale in LocaleResolver

Page 62: Spring 4 - A&BP CC

62

Comprehensive time zone support (8)

▪ Possible TimeZone scenario:- TimeZone info passed as a request parameter (ex: JavaScript function

returning TimeZone)- Extending LocaleChangeInterceptor (writing own interceptor) to

handle TimeZone info and setting the correct LocaleContext in LocaleContextResolver

Page 63: Spring 4 - A&BP CC

63

Spring 4.1 web improvement

▪ There is a number of small and bigger improvements. Further, in this presentation some of them will be highlighted.

▪ For the complete and comprehensive list of the improvements, please, consult the Spring documentation

Page 64: Spring 4 - A&BP CC

64

JDK 1.8’s java.util.Optional support

▪ Optional is now supported for @RequestParam, @RequestHeader, and @MatrixVariable controller method arguments.

▪ DEMO

Page 65: Spring 4 - A&BP CC

65

@JsonView

▪ Jackson’s @JsonView is supported directly on @ResponseBody and ResponseEntity controller methods for serializing different amounts of detail for the same POJO (e.g. summary vs. detail page).

▪ Also supported with View-based rendering by adding the serialization view type as a model attribute under a special key.

▪ DEMO

Page 66: Spring 4 - A&BP CC

66

New type: RequestEntity

▪ Provides a builder-style API to guide client-side REST code towards the preparation of HTTP requests.

▪ For example:

Page 67: Spring 4 - A&BP CC

67

ResponseEntity provides builder-style API

▪ Example:

Page 69: Spring 4 - A&BP CC

WebSockets

Page 70: Spring 4 - A&BP CC

In the beginning there was… polling

Do you have new data?

Page 71: Spring 4 - A&BP CC

In the beginning there was… polling (2)

Do you have new data?

No

Page 72: Spring 4 - A&BP CC

In the beginning there was… polling (3)

Page 73: Spring 4 - A&BP CC

In the beginning there was… polling (4)

Do you have new data?

Page 74: Spring 4 - A&BP CC

In the beginning there was… polling (5)

Do you have new data?

No

Page 75: Spring 4 - A&BP CC

In the beginning there was… polling (6)

Page 76: Spring 4 - A&BP CC

In the beginning there was… polling (7)

Page 77: Spring 4 - A&BP CC

Long polling

Do you have new data?

Page 78: Spring 4 - A&BP CC

Long polling (2)

Do you have new data?

Page 79: Spring 4 - A&BP CC

Long polling (3)

Do you have new data?

Here is your data

Page 80: Spring 4 - A&BP CC

Polling disadvantages

● Client initiates a request (even with long polling mechanism)

● Traffic and overhead (even if there is no data!)

● Big delay between event and notification

● Consider server loads

Page 81: Spring 4 - A&BP CC

And with HTML5 came… WebSockets!

What do you think about a protocol upgrade?

Page 82: Spring 4 - A&BP CC

And with HTML5 came… WebSockets! (2)

What do you think about a protocol upgrade?

Sure, why not!HTTP 101 Switching Protocols

Page 83: Spring 4 - A&BP CC

And with HTML5 came… WebSockets! (3)

Open TCP socket

Page 84: Spring 4 - A&BP CC

What about AJAX? Can I still use it?

AJAX

High latency (HTTP req/res for each

roundtrip)

Small to medium messages

WebSockets

Low latency (TCP socket remains

open)

Large and frequent messages

Realtime applications (stocks,

games, …)

● Not every project needs WebSockets!

Page 85: Spring 4 - A&BP CC

WebSockets in Spring

● New Spring WebSocket module

● Fallback option with SockJS

● as underlying sub-protocol (https://stomp.github.io/)

○ Simple interoperable protocol for asynchronous messaging

○ Client actions: SEND, SUBSCRIBE / UNSUBSCRIBE, ACK / NACK

○ Server actions: MESSAGE, RECEIPT, ERROR

Page 86: Spring 4 - A&BP CC

WebSockets in Spring (2)

● Generic Spring Messaging Module

○ Some Spring integration types promoted to Core (eg. Message, @MessageMapping, …)

○ Also usable when using JMS

Page 87: Spring 4 - A&BP CC

WebSockets in Spring (3)

@EnableWebSocket @EnableWebSocketMessageBroker

Raw WebSocket handler support

Extend TextWebSocketHandler or BinaryWebSocketHandler and implement handleTextMessage

WebSocket using a higher-level messaging sub-protocol (eg. STOMP)

Page 88: Spring 4 - A&BP CC

Raw example

import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.WebSocketSession;import org.springframework.web.socket.TextMessage;

public class MyHandler extends TextWebSocketHandler { @Override public void handleTextMessage(WebSocketSession session, TextMessage msg) { // ... }}

Page 89: Spring 4 - A&BP CC

Raw example (2)

@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer {

@Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/myHandler"); }

@Bean public WebSocketHandler myHandler() { return new MyHandler(); }}

Page 90: Spring 4 - A&BP CC

Demo application

● AngularJS application

● Spring WebMVC backend

● SockJS with higher-level STOMP protocol and Jackson serialization

Page 91: Spring 4 - A&BP CC

Testing improvements

Page 92: Spring 4 - A&BP CC

Cleaning up after Spring 3.x

Page 93: Spring 4 - A&BP CC

Cleaning up after Spring 3.x (2)

● Many packages/classes/methods were marked as deprecated in the Spring 3.x version

● In Spring 4.x:

○ All deprecated packages have been removed

○ Many deprecated methods and fields have been removed

● Before upgrading from 3.x to 4.x → Look at the deprecation warnings!

Page 94: Spring 4 - A&BP CC

Pruning in Spring 4.0

● Several things have been pruned to improve the testing experience

< 4.0 4.0+

No more JUnit 3.8 support Use JUnit 4 or TestNG

@ExpectedException Use @Test(expected = MyEx.class) or @Rule

@NotTransactional Use @Transactional(propagation = NOT_SUPPORTED)

SimpleJdbcTestUtils Use JdbcTestUtils or ScriptUtils or @Sql

Page 95: Spring 4 - A&BP CC

Changes in dependencies in Spring 4.0

● Servlet API mocks → upgraded to Servlet 3.0 API

○ Servlet 3.0 API is easier, more powerful and more versatile

○ Servlet 2.5 API is still supported

● JUnit

○ minimum version 4.8

○ recommended version 4.11

● TestNG → Use version 6.8.5

Page 96: Spring 4 - A&BP CC

Changes in dependencies in Spring 4.1

● Servlet API mocks → upgraded to Servlet 3.0 API

○ Servlet 3.0 API is easier, more powerful and more versatile

○ Servlet 2.5 API is still supported

● JUnit

○ minimum version 4.9 is supported

○ version 4.11 is recommended

● TestNG

○ version 6.8.8 is recommended

Page 97: Spring 4 - A&BP CC

New in Spring 4.0

● SocketUtils

○ Used to scan for available UDP and TCP ports

○ Handy for setting up different containers / servers during integration tests

● ActiveProfilesResolver API

○ Programmatic alternative to static profile strings (like in Spring 3.x)

○ Use the resolver attribute in @ActiveProfiles annotation

● Meta-annotation support for tests

○ Easy to create annotations for your annotations

Page 98: Spring 4 - A&BP CC

New in Spring 4.1

● Groovy scripts can be used to configure your Spring context

● Programmatically start/stop/commit your test transaction with TestTransaction

● Default & Custom TestExecutionListeners can now be automatically discovered

● Custom TestExecutionListeners can be merged with the default ones

● @Sql and @SqlConfig allow you to configure execution of SQL scripts declaratively:

○ before/after a test class

○ before/after a test method

Page 99: Spring 4 - A&BP CC

Demo

Page 100: Spring 4 - A&BP CC

Questions