文档章节

Java 8在Spring 4中的使用

Bieber
 Bieber
发布于 2015/02/13 15:33
字数 1564
阅读 160
收藏 2

#Java 8在Spring 4中的使用# Spring4已经发布一段时间了,但是在国内大部分企业还一直沉浸在Spring 3.x的时代。今天无意在Infoq看到一片关于Spring 4中对Java 8性功能的使用,趁机看看Spring 4的功能以及Java 8 的一些新特性。

这篇文章大部分内容是翻译自:http://www.infoq.com/articles/spring-4-java-8

##Spring 4对Lambda表达式的应用## 在JDK中存在很多回调接口,老外叫做方法接口。比如RunnableComparable,Listener类的接口等等,这种接口我们一般习惯通过匿名类的方式实现它,它们的特点包括:接口定义简单(一般就一两个方法),我们只需要new出它们,但是从来不是我们调用它们,一般用于通知类型的场景。在Spring中类似这些接口也有很多,这里只列举出JDBC相关的接口:

<!--lang:java-->
public interface ConnectionCallback<T> {
	T doInConnection(Connection con) throws SQLException, DataAccessException;
}

public interface RowMapper<T>
{
	T mapRow(ResultSet rs, int rowNum) throws SQLException;
 }

JdbcTemplate下存在下面方法:

<!--lang:java-->
public <T> List<T> query(String sql, RowMapper<T> rowMapper) throws DataAccessException

在Java 8之前我们是如下方式调用的:

<!--lang:java-->
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;
}
});

但是在Java 8下面,我们可以通过Lambda表达式的方式:

<!--lang:java-->
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;
});

这里我们并没有实例化一个RowMapper类,而是通过Lambda的方式来执行,相对之前简单明了。当然这需要Java 8的支持。依次类推,在Java 8下可以执行下面代码:

<!--lang:java-->
new Thread(()->{
	//do run method 	
});

关于Lambda可以参照相关的资料,由于这里不是介绍Lambda的,而且我也不熟悉,所以就不误导大家了!

##Spring 4和Java 8最新时间日期API## 在Java 8之前,我们对日期的操作用的比较多的就是两个类(Date,SimpleDateFormate),用于时间转换和表示时间对象。在Java 8中提供了更加丰富的时间API,在java.time包下面有很多新的类来操作时间日期相关的类,比如:LocalDate,LocalTime以及LocalDateTime。Spring 4对这些新的API进行了兼容。例如下面的代码:

<!--lang:java-->
@RestController
public class ExampleController {

@RequestMapping("/date/{localDate}")
public String get(@DateTimeFormat(iso = ISO.DATE)LocalDate localDate)
{
	return localDate.toString();
}
}

如果localDate参数值是2015-02-13那么将会自动转换成LocalDate类的实体。

但是这只是Spring 4对它进行了支持,但是在SSH或者SSI其他第三方非Spring 4的项目中可能没有对其进行支持,所以不能说项目里面有了Spring 4就能放心的使用这些最新的日期时间API来做日期转换。

##Spring 4支持重复注解##

Java8之前,在同一个作用域不能配置相同的注解,不然会提示唯一注解的错误。但是Java8以后,支持了重复的注解,即一个作用域上面同一个注解可以配置多次。代码如下:

<!--lang:java-->
@Configuration
@ComponentScan
@EnableAutoConfiguration
@PropertySource("classpath:/example1.properties")
@PropertySource("classpath:/example2.properties")
public class Application {

@Autowired
private Environment env;

@Bean
public JdbcTemplate template(DataSource datasource) {
	System.out.println(env.getProperty("test.prop1"));
	System.out.println(env.getProperty("test.prop2"));
	return new JdbcTemplate(datasource);
}

public static void main(String[] args) {
	SpringApplication.run(Application.class, args);
}
}

但是这里是要有意义的重复配置,而不是无聊的进行配置,比如你对@Autowired重复配置,这个我只能说很无聊咩!

##Java 8 Optional<>在Spring 4.1的使用##

我们在开发过程中,如果对一个方法返回结果,在不确定他是非空的时候,都要进行非空校验,以防止出现空指针异常。于是Java 8针对这种情况,提供了一个统一的处理,就是Optional。先看看怎么用它:

之前我们这样来进行空校验:

<!--lang:java-->
Customer customer = customerRepository.findCustomerById(“123”);
if(customer != null) {
	customer.getName(); // avoid a null pointer exception
}

java 8里利用Optional可以如下来做:

<!--lang:java-->
public interface CustomerRepository extends CrudRepository<Customer, Long> {
public Optional<Customer> findCustomerById(String id);
}


//在其他方法调用:
Optional<Customer> optional = customerRepository.findCustomerById(“123”);
if(optional.isPresent()) {
	Customer customer = optional.get();
	customer.getName();
}

个人感觉也没简单而已,只是没出现了null关键词,那Spring怎么来使用它的呢?Spring一般用在对Bean的注入的时候,当我们配置某个不是必须注入的,可以通过这种方式来用,具体代码如下:

之前代码:

<!--lang:java-->
@Service
public class MyService {

    @Autowired(required=false)
    OtherService otherService;

    public doSomething() {
      if(otherService != null) {
        // use other service
      }
   	}
}

使用Optional之后:

<!--lang:java-->
public class MyService {

    @Autowired
    Optional<OtherService> otherService;

    public doSomething() {
      otherService.ifPresent( s ->  {
        // use s to do something
      });
    }
}

##可以获取方法参数名## java 8之前,通过反射是无法获取方法参数名称的,Field只能获得类型,但是java 8以后将参数名称存储在了类文件中,于是可以通过反射获取方法参数的名称。这个对于我来说是一个惊喜,之前为了能够获取方法参数需要增加多少配置,弄得很是蹩脚,现在,可以放开脚步走了。带着这个特性,可以带来很多好处,下面列举出部分例子:

Java 8之前:

<!--lang:java-->
@RequestMapping("/accounts/{id}")
public Account getAccount(@PathVariable("id") String id)

Java 8之后: @RequestMapping("/accounts/{id}") public Account getAccount(@PathVariable String id)

不在指定参数名称了,只要保持你方法参数和引用的参数名称一样即可。是否小激动了一把?

又例如:

Java 8之前:

<!--lang:java-->
interface CustomerRepository extends CrudRepository<Customer, Long> {
@Query("select c from Customer c where c.lastname = :lastname")
List<Customer> findByLastname(@Param("lastname") String lastname);
}

Java 8之后:

<!--lang:java-->
interface CustomerRepository extends CrudRepository<Customer, Long> {
@Query("select c from Customer c where c.lastname = :lastname")
List<Customer> findByLastname(String lastname);
}

借助这篇文章也体验了一下Java 8的新特性。更多的特性还需真正引用的时候去发现。

© 著作权归作者所有

共有 人打赏支持
Bieber
粉丝 208
博文 36
码字总数 83312
作品 1
杭州
高级程序员
Spring MVC 使用 JNDI 配置的DataSource

稍微看了下,Spring 中JNDI 的使用,弄了个小例子。有很多不完备的地方,以后慢慢看,再改吧。 <一> 技术使用 Spring MVC JDBC Template Maven JNDI <二> 一些配置 Maven POM 配置 spring-c...

平江夜弹
2015/06/29
0
0
Spring Boot 配置加载顺序详解

使用 Spring Boot 会涉及到各种各样的配置,如开发、测试、线上就至少 3 套配置信息了。Spring Boot 可以轻松的帮助我们使用相同的代码就能使开发、测试、线上环境使用不同的配置。 在 Spri...

Java技术栈
08/27
0
0
【第2章 Spring快速入门】2.1 Java应用之HelloWorld

上一节:【第1章 Spring概述与结构】1.2 Spring模块与结构 注意:本系列教程不会通过工程单独依赖某个Jar包,而是通过开源中国的Maven库,来进行Jar包的依赖管理,所以后续的讲解都是以Maven...

陶邦仁
2015/05/24
0
3
spring ioc注解 IOC

@Autowired 1、Spring 通过一个 BeanPostProcessor 对 @Autowired 进行解析,所以要让 @Autowired 起作用必须事先在 Spring 容器中声明 AutowiredAnnotationBeanPostProcessor Bean。 Java代...

五大三粗
2015/11/02
0
0
Spring Boot实战之基础回顾

本文作者: 吴伟祥 本文链接: https://wuweixiang.cn/2018/08/21/Spring-Boot实战之基础回顾/ 版权声明: 本博客所有文章除特别声明外均为原创,采用CC BY-NC-SA 4.0 许可协议。转载请在文章开...

吴伟祥
08/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

20180920 rzsz传输文件、用户和用户组相关配置文件与管理

利用rz、sz实现Linux与Windows互传文件 [root@centos01 ~]# yum install -y lrzsz # 安装工具sz test.txt # 弹出对话框,传递到选择的路径下rz # 回车后,会从对话框中选择对应的文件传递...

野雪球
15分钟前
0
0
OSChina 周四乱弹 —— 毒蛇当辣条

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ 达尔文:分享花澤香菜/前野智昭/小野大輔/井上喜久子的单曲《ミッション! 健?康?第?イチ》 《ミッション! 健?康?第?イチ》- 花澤香菜/前野智...

小小编辑
今天
5
2
java -jar运行内存设置

java -Xms64m #JVM启动时的初始堆大小 -Xmx128m #最大堆大小 -Xmn64m #年轻代的大小,其余的空间是老年代 -XX:MaxMetaspaceSize=128m # -XX:CompressedClassSpaceSize=6...

李玉长
今天
1
0
Spring | 手把手教你SSM最优雅的整合方式

HEY 本节主要内容为:基于Spring从0到1搭建一个web工程,适合初学者,Java初级开发者。欢迎与我交流。 MODULE 新建一个Maven工程。 不论你是什么工具,选这个就可以了,然后next,直至finis...

冯文议
今天
1
0
RxJS的另外四种实现方式(四)——性能最高的库(续)

接上一篇RxJS的另外四种实现方式(三)——性能最高的库 上一篇文章我展示了这个最高性能库的实现方法。下面我介绍一下这个性能提升的秘密。 首先,为了弄清楚Most库究竟为何如此快,我必须借...

一个灰
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部