Spring 4支持的Java 8新特性一览

时间:2017-12-05 08:58

有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分。有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持。本文将带您浏览Spring 4.0和4.1已经支持的Java 8新特性。

Spring 4支持Java 6、7和8

Java 8编译器编译过的代码生成的.class文件需要在Java 8或以上的Java虚拟机上运行。由于Spring对反射机制和ASM、CGLIB等字节码操作函数库的重度使用,必须确保这些函数库能理解Java 8生成的新class文件。因此Spring将ASM、CGLIB等函数库通过jar jar(https://code.google.com/p/jarjar/)嵌入Spring框架中,这样Spring就可以同时支持Java6、7和8的字节码代码而不会触发运行时错误。

Spring框架本身是由Java 8编译器编译的,编译时使用的是生成Java 6字节码的编译命令选项。因此你可以Java6、7或者8来编译运行Spring 4.x的应用。

Spring和Java 8的Lambda表达式

相关厂商内容

京东虚拟商品系统如何做高可用架构设计? 顶尖架构师岁末总结大会:上百技术案例日程出炉! 不改一行代码:左耳朵看微服务调度的三大件 AI时代,我到底该如何跟上技术潮流? Fintech 技术突围之道 | ArchSummit 限额免费专场

相关赞助商

Spring 4支持的Java 8新特性一览

Java 8的设计者想保证它是向下兼容的,以使其lambda表达式能在旧版本的代码编译器中使用。向下兼容通过定义函数式接口概念实现。

基本上,Java 8的设计者分析了现有的Java代码体系,注意到很多Java程序员用只有一个方法的接口来表示方法的思想。以下就是JDK和Spring中只有一个方法的接口的例子,也就是所谓的“函数式接口”。

JDK里的函数式接口:

public interface Runnable { public abstract void run();} public interface Comparable<T> { public int compareTo(T o);}

Spring框架里的函数式接口:

public interface ConnectionCallback<T> { T doInConnection(Connection con) throws SQLException, DataAccessException;} public interface RowMapper<T>{ T mapRow(ResultSet rs, int rowNum) throws SQLException;}

在Java 8里,任何函数式接口作为方法的参数传入或者作为方法返回值的场合,都可以用lambda表达式代替。例如,Spring的JdbcTemplate类里有一个方法定义如下:

public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException

这个查询方法的第二个参数需要RowMapper接口的一个实例。在Java 8中我们可以写一个lambda表达式作为第二个参数的值传进去。

别把代码写成这样:

jdbcTemplate.query("SELECT * from products", new RowMapper<Product>(){ @Override public Product mapRow(ResultSet rs, int rowNum) throws SQLException { Integer id = rs.getInt("id"); String description = rs.getString("description"); Integer quantity = rs.getInt("quantity"); BigDecimal price = rs.getBigDecimal("price"); Date availability = rs.getDate("available_date"); Product product = new Product(); product.setId(id); product.setDescription(description); product.setQuantity(quantity); product.setPrice(price); product.setAvailability(availability); return product; }});

我们这么写:

jdbcTemplate.query("SELECT * from queries.products", (rs, rowNum) -> { Integer id = rs.getInt("id"); String description = rs.getString("description"); Integer quantity = rs.getInt("quantity"); BigDecimal price = rs.getBigDecimal("price"); Date availability = rs.getDate("available_date"); Product product = new Product(); product.setId(id); product.setDescription(description); product.setQuantity(quantity); product.setPrice(price); product.setAvailability(availability); return product;});

我们注意到Java 8中这段代码使用了lambda表达式,这比之前的版本中使用匿名内部类的方式紧凑、简洁得多。

涵盖Java 8中函数式接口的所有细节超出了本文的范畴,我们强烈建议您从别处详细学习函数式接口。本文想要传达的关键点在于Java 8的lambda表达式能传到那些用Java 7或更早的JDK编译的、接受函数式接口作为参数的方法中。

Spring的代码里有很多函数式接口,因此lambda表达式很容易与Spring结合使用。即便Spring框架本身被编译成Java 6的.class文件格式,你仍然可以用Java 8的lambda表达式编写应用代码、用Java 8编译器编译、并且在Java 8虚拟机上运行,你的应用可以正常工作。