Spring on Java 8
Transcript of Spring on Java 8
![Page 1: Spring on Java 8](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/1.jpg)
© 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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/2.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/3.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/4.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/5.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/6.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/7.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/8.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/9.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/10.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/11.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/12.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/13.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/14.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/15.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/16.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/17.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/18.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/19.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/20.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/21.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/22.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/23.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/24.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/25.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/26.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/27.jpg)
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](https://reader034.fdocuments.us/reader034/viewer/2022042615/55d578d9bb61eba42f8b45c3/html5/thumbnails/28.jpg)
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