Spring4新特性——Web开发的增强
 

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

 

从Spring4开始,Spring以Servlet3为进行开发,如果用Spring MVC 测试框架的话需要指定Servlet3兼容的jar包(因为其Mock的对象都是基于Servlet3的)。另外为了方便Rest开发,通过新的 @RestController指定在控制器上,这样就不需要在每个@RequestMapping方法上加 @ResponseBody了。而且添加了一个AsyncRestTemplate ,支持REST客户端的异步无阻塞支持。

 

1、@RestController

查看复制到剪贴板打印

  1. @RestController  

  2. public class UserController {  

  3.     private UserService userService;  

  4.     @Autowired  

  5.     public UserController(UserService userService) {  

  6.         this.userService = userService;  

  7.     }  

  8.     @RequestMapping("/test")  

  9.       public User view() {  

  10.         User user = new User();  

  11.         user.setId(1L);  

  12.         user.setName("haha");  

  13.         return user;  

  14.     }  

  15.   

  16.     @RequestMapping("/test2")  

  17.     public String view2() {  

  18.         return "{\"id\" : 1}";  

  19.     }  

  20. }  

 其实现就是在@@RestController中加入@ResponseBody:

查看复制到剪贴板打印

  1. @org.springframework.stereotype.Controller  

  2. @org.springframework.web.bind.annotation.ResponseBody  

  3. public @interface RestController {  

  4. }  

这样当你开发Rest服务器端的时候,spring-mvc配置文件需要的代码极少,可能就仅需如下一行:

查看复制到剪贴板打印

  1. <context:component-scan base-package="com.sishuok.spring4"/>  

  2. <mvc:annotation-driven/>  

  

2、mvc:annotation-driven配置变化

统一风格;将 enableMatrixVariables改为enable-matrix-variables属性;将ignoreDefaultModelOnRedirect改为ignore-default-model-on-redirect。

 

3、提供AsyncRestTemplate用于客户端非阻塞异步支持。

3.1、服务器端

对于服务器端的springmvc开发可以参考https://github.com/zhangkaitao/servlet3-showcase中的chapter3-springmvc

查看复制到剪贴板打印

  1. @RestController  

  2. public class UserController {  

  3.     private UserService userService;  

  4.     @Autowired  

  5.     public UserController(UserService userService) {  

  6.         this.userService = userService;  

  7.     }  

  8.     @RequestMapping("/api")  

  9.       public Callable<User> api() {  

  10.         System.out.println("=====hello");  

  11.         return new Callable<User>() {  

  12.             @Override  

  13.             public User call() throws Exception {  

  14.                 Thread.sleep(10L * 1000); //暂停两秒  

  15.                 User user = new User();  

  16.                 user.setId(1L);  

  17.                 user.setName("haha");  

  18.                 return user;  

  19.             }  

  20.         };  

  21.     }  

  22. }  

非常简单,服务器端暂停10秒再返回结果(但是服务器也是非阻塞的)。具体参考我github上的代码。

 

3.2、客户端

查看复制到剪贴板打印

  1. public static void main(String[] args) {  

  2.     AsyncRestTemplate template = new AsyncRestTemplate();  

  3.     //调用完后立即返回(没有阻塞)  

  4.     ListenableFuture<ResponseEntity<User>> future = template.getForEntity("http://localhost:9080/spring4/api", User.class);  

  5.     //设置异步回调  

  6.     future.addCallback(new ListenableFutureCallback<ResponseEntity<User>>() {  

  7.         @Override  

  8.         public void onSuccess(ResponseEntity<User> result) {  

  9.             System.out.println("======client get result : " + result.getBody());  

  10.         }  

  11.   

  12.         @Override  

  13.         public void onFailure(Throwable t) {  

  14.             System.out.println("======client failure : " + t);  

  15.         }  

  16.     });  

  17.     System.out.println("==no wait");  

  18. }  

 此处使用Future来完成非阻塞,这样的话我们也需要给它一个回调接口来拿结果; Future和Callable是一对,一个消费结果,一个产生结果。调用完模板后会立即返回,不会阻塞;有结果时会调用其回调。

 

AsyncRestTemplate默认使用SimpleClientHttpRequestFactory,即通过 java.net.HttpURLConnection实现;另外我们也可以使用apache的http components;使用template.setAsyncRequestFactory(new HttpComponentsAsyncClientHttpRequestFactory());设置即可。