Spring on Java 8

28
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Spring Framework 4 on Java 8 Juergen Hoeller

Transcript of Spring on Java 8

Page 1: Spring on Java 8

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Spring Framework 4 on Java 8

Juergen Hoeller

Page 2: Spring on Java 8

Spring Framework 4 – a new baseline

• Java SE 6+• minimum API level: JDK 6 update 18, ~ early 2010

• Java EE 6+• Servlet 3.0 focused, Servlet 2.5 compatible at runtime

• Comprehensive support for Java SE 8• language features and APIs

• Explicit support for Java EE 7 level specifications• JMS 2.0, JTA 1.2, JPA 2.1, Bean Validation 1.1, JSR-236

2

Page 3: Spring on Java 8

Feature themes in Spring Framework 4.0

• Injection matching by full generic type

• Generalized model for conditional bean definitions

• Composable annotations with overridable attributes

• General org.springframework.messaging module

• WebSocket endpoint model along the lines of Spring MVC

3

Page 4: Spring on Java 8

Feature themes in Spring Framework 4.1

• Annotated JMS listener methods

• Comprehensive support for JCache (JSR-107) annotations

• Flexible resolution and transformation of static web resources

• MVC views: declarative resolution, Groovy markup templates

• WebSocket refinements: WebSocket scope, SockJS client

4

Page 5: Spring on Java 8

Agenda: Java 8 features in Spring 4.0 / 4.1

• Lambda expressions• Method references• JSR-310 Date and Time• Repeatable annotations• Parameter name discovery• java.util.Optional

• Related new injection features:• Ordering, @Priority, generic types

5

Page 6: Spring on Java 8

Java 8 lambda conventions

• Simple rule: interfaces with single method to be implemented

• Typically callback interfaces such as Runnable or Callable:Executor.execute(Runnable)

• Common functional interfaces in java.util.function:Function, Predicate, Supplier

• A great use case: Java 8's Collection Stream API

6

Page 7: Spring on Java 8

Lambda conventions with Spring APIs

• TransactionTemplate with TransactionCallback:Object doInTransaction(TransactionStatus status)

• JdbcTemplate with PreparedStatementSetter:void setValues(PreparedStatement ps) throws SQLException

• JdbcTemplate with RowMapper:Object mapRow(ResultSet rs, int rowNum) throws SQLException

7

Page 8: Spring on Java 8

Lambdas with Spring's JdbcTemplate (v1)

JdbcTemplate jt = new JdbcTemplate(dataSource);

jt.query("SELECT name, age FROM person WHERE dep = ?",

ps -> ps.setString(1, "Sales"),

(rs, rowNum) -> new Person(rs.getString(1), rs.getInt(2)));

8

Page 9: Spring on Java 8

Lambdas with Spring's JdbcTemplate (v2)

JdbcTemplate jt = new JdbcTemplate(dataSource);

jt.query("SELECT name, age FROM person WHERE dep = ?",

ps -> {

ps.setString(1, "Sales");

},

(rs, rowNum) -> {

return new Person(rs.getString(1), rs.getInt(2));

});

9

Page 10: Spring on Java 8

Method references with Spring's JdbcTemplate

public List<Person> getPersonList(String department) {

JdbcTemplate jt = new JdbcTemplate(this.dataSource);

return jt.query("SELECT name, age FROM person WHERE dep = ?",

ps -> ps.setString(1, "Sales"),

this::mapPerson);

}

private Person mapPerson(ResultSet rs, int rowNum) throws SQLException {

return new Person(rs.getString(1), rs.getInt(2));

}

10

Page 11: Spring on Java 8

JSR-310 Date and Time

import java.time.*;

import org.springframework.format.annotation.*;

public class Customer {

// @DateTimeFormat(iso=ISO.DATE)

private LocalDate birthDate;

@DateTimeFormat(pattern="M/d/yy h:mm")

private LocalDateTime lastContact;

}

11

Page 12: Spring on Java 8

Repeatable annotations

@Scheduled(cron = "0 0 12 * * ?")

@Scheduled(cron = "0 0 18 * * ?")

public void performTempFileCleanup() { ... }

@Schedules({

@Scheduled(cron = "0 0 12 * * ?"),

@Scheduled(cron = "0 0 18 * * ?")

})

public void performTempFileCleanup() { ... }

12

Page 13: Spring on Java 8

Spring's parameter name discovery

• As of 4.0: aware of Java 8's parameter reflection

• Finally, first-class support for parameter names in the JDK!• accessible via common Java reflection methods

• Now checking Java 8 first-parameters

• ASM-based reading of debug symbols next-debug

13

Page 14: Spring on Java 8

Parameter name discovery in action

@Controller

public class MyMvcController {

@RequestMapping(value="/books/{id}", method=GET)

public Book findBook(@PathVariable long id, @RequestHeader String country) {

...

}

}

14

Page 15: Spring on Java 8

MVC handler methods: traditional required flag

@Controller

public class MyMvcController {

@RequestMapping(value="/books/{id}", method=GET)

public Book findBook(@PathVariable long id, @RequestHeader(required=false) String country) {

if (country != null) { ... }

}

}

15

Page 16: Spring on Java 8

New in 4.1: Java 8's java.util.Optional

@Controller

public class MyMvcController {

@RequestMapping(value="/books/{id}", method=GET)

public Book findBook(@PathVariable long id, @RequestHeader Optional<String> country) {

country.ifPresent(value -> ...);

}

}

16

Page 17: Spring on Java 8

Injection points: traditional required flag

@Service

public class MyService {

@Autowired(required=false)

NotificationService notificationService;

public Book findBook(long id) {

If (notificationService != null) { ... }

}

}

17

Page 18: Spring on Java 8

New in 4.1: Optional at injection points

@Service

public class MyService {

@Autowired

Optional<NotificationService> notificationService;

public Book findBook(long id) {

notificationService.ifPresent(service -> ...);

}

}

18

Page 19: Spring on Java 8

Injection points: ordered lists (as of 4.0)

@Service @Order(1)

public class MyServiceImpl implements MyService { ... }

@Service @Order(2)

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

List<MyService> myServices; // MyServiceImpl first

19

Page 20: Spring on Java 8

New in 4.1: @Order on @Bean methods

@Bean @Order(1)

public MyService myServiceX() { return new MyServiceImpl() }

@Bean @Order(2)

public MyService myServiceY() { return new MyOtherServiceImpl() }

@Autowired

List<MyService> myServices; // MyServiceImpl first

20

Page 21: Spring on Java 8

New in 4.1: @javax.annotation.Priority for ordering

@Service @Priority(1)

public class MyServiceImpl implements MyService { ... }

@Service @Priority(2)

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

List<MyService> myServices; // MyServiceImpl first

21

Page 22: Spring on Java 8

Injection: selecting a @Primary candidate

@Service @Primary

public class MyServiceImpl implements MyService { ... }

@Service

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

MyService myService; // MyServiceImpl getting selected!

22

Page 23: Spring on Java 8

Injection: @Order for primary candidate selection?

@Service @Order(1)

public class MyServiceImpl implements MyService { ... }

@Service @Order(2)

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

MyService myService; // FAILS: @Order lacks 'primary' semantics

23

Page 24: Spring on Java 8

Injection: @Order + @Primary works for selection

@Service @Order(1) @Primary

public class MyServiceImpl implements MyService { ... }

@Service @Order(2)

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

MyService myService; // MyServiceImpl getting selected!

24

Page 25: Spring on Java 8

Injection: @Priority for primary candidate selection

@Service @Priority(1) // highest priority -> 'primary' role

public class MyServiceImpl implements MyService { ... }

@Service @Priority(2)

public class MyOtherServiceImpl implements MyService { ... }

@Autowired

MyService myService; // MyServiceImpl getting selected!

25

Page 26: Spring on Java 8

Injection: Qualifiers for candidate selection

@Service @Qualifier("default")

public class MyServiceImpl implements MyService { ... }

@Service

public class MyOtherServiceImpl implements MyService { ... }

@Autowired @Qualifier("default")

MyService myService; // MyServiceImpl getting selected!

26

Page 27: Spring on Java 8

Injection: generic types for selection (as of 4.0)

@Service

public class MyServiceImpl implements MyService<Entity> { ... }

@Service

public class MyOtherServiceImpl implements MyService<Event> { }

@Autowired

MyService<Entity> myService; // MyServiceImpl getting selected!

27

Page 28: Spring on Java 8

Summary: Java 8 features in Spring 4.0 / 4.1

• Lambda expressions• Method references• JSR-310 Date and Time• Repeatable annotations• Parameter name discovery• java.util.Optional

• Related new injection features:• Ordering, @Priority, generic types

28