Spring 4支持的Java 8新特性一览.doc_第1页
Spring 4支持的Java 8新特性一览.doc_第2页
Spring 4支持的Java 8新特性一览.doc_第3页
Spring 4支持的Java 8新特性一览.doc_第4页
Spring 4支持的Java 8新特性一览.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Spring 4支持的Java 8新特性一览有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分。有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持。本文将带您浏览Spring 4.0和4.1已经支持的Java 8新特性。Spring4支持Java 6、7和8Java 8编译器编译过的代码生成的.class文件需要在Java 8或以上的Java虚拟机上运行。由于Spring对反射机制和ASM、CGLIB等字节码操作函数库的重度使用,必须确保这些函数库能理解Java 8生成的新class文件。因此Spring将ASM、CGLIB等函数库通过jar jar(/p/jarjar/)嵌入Spring框架中,这样Spring就可以同时支持Java6、7和8的字节码代码而不会触发运行时错误。Spring框架本身是由Java 8编译器编译的,编译时使用的是生成Java 6字节码的编译命令选项。因此你可以Java6、7或者8来编译运行Spring 4.x的应用。Spring和Java 8的Lambda表达式Java 8的设计者想保证它是向下兼容的,以使其lambda表达式能在旧版本的代码编译器中使用。向下兼容通过定义函数式接口概念实现。基本上,Java 8的设计者分析了现有的Java代码体系,注意到很多Java程序员用只有一个方法的接口来表示方法的思想。以下就是JDK和Spring中只有一个方法的接口的例子,也就是所谓的“函数式接口”。JDK里的函数式接口:public interface Runnable public abstract void run();public interface Comparable public int compareTo(T o);Spring框架里的函数式接口:public interface ConnectionCallback T doInConnection(Connection con) throws SQLException, DataAccessException;public interface RowMapper T mapRow(ResultSet rs, int rowNum) throws SQLException;在Java 8里,任何函数式接口作为方法的参数传入或者作为方法返回值的场合,都可以用lambda表达式代替。例如,Spring的JdbcTemplate类里有一个方法定义如下:public List query(String sql, RowMapper rowMapper) throws DataAccessException这个查询方法的第二个参数需要RowMapper接口的一个实例。在Java 8中我们可以写一个lambda表达式作为第二个参数的值传进去。别把代码写成这样:jdbcTemplate.query(SELECT * from products, new RowMapper() 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 ducts, (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虚拟机上运行,你的应用可以正常工作。总之,因为Spring框架早在Java 8正式给函数式接口下定义之前就已经实际使用了函数式接口,因此在Spring里使用lambda表达式非常容易。Spring 4和Java 8的时间与日期APIJava开发者们一直痛恨java.util.Date类的设计缺陷,终于,Java 8带来了全新的日期与时间API,解决了那些久被诟病的问题。这个新的日期与时间API值得用一整篇文章的篇幅来讲述,因此我们在本文不会详述其细节,而是重点关注新的java.time包中引入的众多新类,如LocalDate、LocalTime和 LocalDateTime。Spring有一个数据转换框架,它可以使字符串和Java数据类型相互转换。Spring 4升级了这个转换框架以支持Java 8日期与时间API里的那些类。因此你的代码可以这样写:RestControllerpublic class ExampleController RequestMapping(/date/localDate) public String get(DateTimeFormat(iso = ISO.DATE) LocalDate localDate) return localDate.toString(); 上面的例子中,get方法的参数是Java 8的LocalDate类型,Spring 4能接受一个字符串参数例如2014-02-01并将它转换成Java 8 LocalDate的实例。要注意的是Spring通常会与其它一些库一起使用实现特定功能,比如与Hibernate一起实现数据持久化,与Jackson一起实现Java对象和JSON的互相转换。虽然Spring 4支持Java 8的日期与时间库,这并不表示第三方框架如Hibernate和Jackson等也能支持它。到本文发表时,Hibernate JIRA里仍有一个开放状态的请求HHH-8844要求在Hibernate里支持Java 8日期与时间API。Spring 4与重复注解Java 8增加了对重复注解的支持,Spring 4也同样支持。特殊的是,Spring 4支持对注解Scheduled和PropertySource的重复。例如,请注意如下代码片段中对PropertySource注解的重复使用:ConfigurationComponentScanEnableAutoConfigurationPropertySource(classpath:/perties)PropertySource(classpath:/perties)public class Application Autowired private Environment env; Bean public JdbcTemplate template(DataSource datasource) System.out.println(env.getProperty(p1); System.out.println(env.getProperty(p2); return new JdbcTemplate(datasource); public static void main(String args) SpringApplication.run(Application.class, args); Java 8的Optional与Spring 4.1忘记检查空值引用是应用代码中一类常见的bug来源。消除NullPointerExceptions的方式之一是确保方法总是返回一个非空值。例如如下方法:public interface CustomerRepository extends CrudRepository /* * returns the customer for the specified id or * null if the value is not found */ public Customer findCustomerById(String id);用如下有缺陷的代码来调用CustomerRepository :Customer customer = customerRepository.findCustomerById(“123”);customer.getName(); / 得到空指针错误这段代码的正确写法应该是:Customer customer = customerRepository.findCustomerById(“123”);if(customer != null) customer.getName(); / 避免空指针错误理想状态下,如果我们没有检查某个值能否为空,我们希望编译器及时发现。java.util.Optional类让我们可以像这样写接口:public interface CustomerRepository extends CrudRepository public Optional findCustomerById(String id);这样一来,这段代码的有缺陷版本不会被编译,开发者必须显式地检查这个Optional类型对象是否有值,代码如下:Optional optional = customerRepository.findCustomerById(“123”);if(optional.isPresent() Customer customer = optional.get(); customer.getName();所以Optional的关键点在于确保开发者不用查阅Javadoc就能知道某个方法可以返回null,或者可以把一个null值传给某方法。编译器和方法签名有助于开发者明确知道某个值是Optional类型。关于Optional类思想的详细描述请参考这里。Spring 4.1有两种方式支持Java Optional。Spring的Autowired注解有一个属性required,使用之后我们可以把如下代码:Servicepublic class MyService Autowired(required=false) OtherService otherService; public doSomething() if(otherService != null) / use other service 替换成:public class MyService Autowired Optional otherService; public doSomething() otherService.ifPresent( s - / use s to do something ); 另一个能用Optional的地方是Spring MVC框架,可以用于表示某个处理方法的参数是可选的。例如:RequestMapping(“/accounts/accountId”,requestMethod=RequestMethod.POST)void update(Optional accountId, RequestBody Account account)这段代码会告诉Spring其accountId是可选参数。总之,Java 8的Optional类通过减少空指针错误相关的缺陷简化了代码编写,同时Spring能很好地支持Java 8的Optional类。参数名发现机制Java 8支持在编译后的代码中保留方法的参数名。这意味着Spring 4可以从方法中提取参数名,从而使SpringMVC代码更为简洁。例如:RequestMapping(/accounts/id)public Account getAccount(PathVariable(id) String id)可以改写为:RequestMapping(/accounts/id)public Account getAccount(PathVariable String id)可以看到我们把PathVariable(“id”) 替换成PathVariable,因为Spring 4能从编译后的Java 8代码中获取参数名id。只要在编译时指定了parameters标记,Java 8编译器就会把参数名写入.class文件中。在Java 8发布之前,Spring也可以从使用-debug选项编译之后的代码中提取出参数名。在Java 7及之前的版本中,-debug选项不会保留抽象方法的参数名。这会导致Spring Data这类基于Java接口自动生成其资源库实现的工程就会出现问题。比如接口如下:interface CustomerRepository extends CrudRepository Query(select c from Customer c where c.lastname = :lastname) List findByLastname(Param(lastname) String lastname)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论