文档章节

Java 8在Spring 4中的使用

Bieber
 Bieber
发布于 2015/02/13 15:33
字数 1564
阅读 164
收藏 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?

一、Web应用开发背景 使用Java做Web应用开发已经有近20年的历史了,从最初的Servlet1.0一步步演化到现在如此多的框架、库以及整个生态系统。经过这么长时间的发展,Java作为一个成熟的语言,...

Ala6
2018/10/10
0
0
Spring Boot 配置加载顺序详解

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

Java技术栈
2018/08/27
0
0
Spring Batch 4.0.0 正式发布,批处理框架

Spring Batch 4.0.0 已发布,Spring Batch 是一个轻量级的,完全面向 Spring 的批处理框架,可以应用于企业级大量的数据处理系统。Spring Batch 以 POJO 和 Spring 框架为基础,使开发者更容...

王练
2017/12/05
3.6K
5
Java 这一年:IntelliJ 称霸 IDE,Kotlin 成最大赢家!

作者 | 帝都羊 投稿 | 架构师小秘圈 Java 版本使用占比 毫无疑问,Java 8 被广泛用于生产环境! Java 9 和 Java 10 的使用率非常低,不到 5%。2017 年,Java 7 和更早的版本的数量大约是 24...

CSDN资讯
2018/12/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【转】初次提交项目到github

第一步:安装Git 第二步:在自己的工程目录下右键鼠标 选择 Git Bash Here 执行命令 git init 来创建一个本地代码仓库 执行命令 git add . 来把所有文件添加到仓库 执行命令 git commit -m ...

覃光林
5分钟前
0
0
Zend Studio使用教程:使用PHPUnit检测代码(五)

本教程演示如何在代码上创建和运行PHPUnit Test。您将学习如何创建和运行包含许多测试用例的单个单元测试用例和测试套件。 单元测试是一个测试代码的过程,以确保源代码的各个单元正常工作,...

电池盒
5分钟前
0
0
前端 联想搜索下拉框

data.result 为联想搜索出来的数组 innerhtml += "<ul style='list-style:none;font-size:13px;margin: 0px;padding: 5px;'>";for (var j = 0; j < data.result.length; j++) { var r......

yan_liu
6分钟前
0
0
预计2019年发布的Vue3.0到底有什么不一样的地方?

摘要: Vue 3.0预览。 原文:预计今年发布的Vue3.0到底有什么不一样的地方? 作者:小肆 Fundebug经授权转载,版权归原作者所有。 还有几个月距离 vue2 的首次发布就满 3 年了,而 vue 的作者...

Fundebug
6分钟前
0
0
跟我学Spring Cloud(Finchley版)-11-Feign常见问题总结

本文总结Feign常见问题及解决方案。 一、FeignClient接口如使用@PathVariable ,必须指定value属性 代码示例: @FeignClient("microservice-provider-user")public interface UserFeignCli......

周立_ITMuch
7分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部