文档章节

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?

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

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

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

Java技术栈
08/27
0
0
Spring Boot实战之基础回顾

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

吴伟祥
08/21
0
0
SpringBoot实战(四)之使用JDBC和Spring访问数据库

这里演示的是h2databse示例,所以简单的介绍普及下h2database相关知识 H2数据库是一个开源的关系型数据库。 H2是一个嵌入式数据库引擎,采用java语言编写,不受平台的限制,同时H2提供了一个...

youcongtech
08/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

0015-如何使用Sentry管理Hive外部表权限

1.文档编写目的 本文档主要讲述如何使用Sentry对Hive外部表权限管理,并基于以下假设: 1.操作系统版本:RedHat6.5 2.CM版本:CM 5.11.1 3.集群已启用Kerberos和Sentry 4.采用具有sudo权限的...

Hadoop实操
7分钟前
0
0
边缘计算与数据中心的发展趋势

导读 Gartner研究表明,人工智能、物联网和5G助力下一代商业创新,由此产生大量数据,2020年前企业将使用超过75亿台联网设备。 在几乎每个方面,社会的节奏都正变得更快。我们希望客户服务问...

问题终结者
20分钟前
3
0
toString();

package com.atguigu.java1; import java.util.Date; /** * toString()的使用: * * 1.java.lang.Object类中toString()定义如下: * public String toString() { return getClass().getName......

architect刘源源
47分钟前
1
3
不可不说的Java“锁”事

前言 Java提供了种类丰富的锁,每种锁因其特性的不同,在适当的场景下能够展现出非常高的效率。本文旨在对锁相关源码(本文中的源码来自JDK 8)、使用场景进行举例,为读者介绍主流锁的知识点...

Java干货分享
50分钟前
1
0
Java GoEasy 实现服务端推送和Web端推送

项目中需要消息推送,又想降低开发成本。Java服务器端推送,Web端接收推送信息。 具体需求: 需求一:系统框架实现全局异常捕获并录入日志表,实现实时推送消息到客户端页面展示。 需求二:系...

Gibbons
52分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部