这章这么少,主要是感觉这两个比较重要,所以单独提取出来写了一篇
1 @RestController
从Spring4.0开始,Spring以Servlet3.0位基础进行开发。如果使用SpringMVC测试框架,则需要指定Servlet3.0兼容的JAR包,因为其Mock的对象都是基于Servlet3.0的。为方便REST风格的开发,Spring引入了一个新的@RestController注解,该注解已经标注了@ResponseBody和@Controller。
这样,通过直接在Controller上添加新的@RestController,就不需要在每个方法上添加@ResponseBody了。
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Controller;
//spring版本为 4.3.2
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}
这样通过直接在Controller上直接添加新的@RestController,就不需要在每个@RequestMapping方法上添加@ResponseBody了。
@Target:
@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。
作用:用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
取值(ElementType)有:
[1].CONSTRUCTOR:用于描述构造器
[2].FIELD:用于描述域
[3].LOCAL_VARIABLE:用于描述局部变量
[4].METHOD:用于描述方法
[5].PACKAGE:用于描述包
[6].PARAMETER:用于描述参数
[7].TYPE:用于描述类、接口(包括注解类型) 或enum声明
@Retention:
@Retention定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。使用这个meta-Annotation可以对 Annotation的“生命周期”限制。
作用:表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效)
取值(RetentionPoicy)有:
[1].SOURCE:在源文件中有效(即源文件保留)
[2].CLASS:在class文件中有效(即class保留)
[3].RUNTIME:在运行时有效(即运行时保留)
@Documented:
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。
@RestController
public class UserController{}
当我们使用REST风格开发时,SpringMVC仅需两行配置就可以了:
<context:component-scan base-package="com.xxx.*"/>
<mvc:annotation-driven/>
2 AsyncRestTemplate
Spring4.0添加了一个AsyncRestTemplate,支持以异步无阻塞的方式进行服务访问。例:
@RestController("userController")
public class UserController{
@Autowired
private UserService userService;
@RequestMapping("/getUser")
public Callable<User> getUser(){
return new Callable<User>(){
@Override
public User call()throws Exception{
Thread.sleep(10L * 1000);//睡10秒
User user = new User();
user.setId(1);
user.setName("haha");
return user;
}
}
}
}
public static void main(String[] args){
AsyncRestTemplate template = new AsyncRestTemplate();
//调用完成立即返回没有阻塞。带服务器端返回请求响应后会自动异步调用下面的回调函数
ListenableFuture<ResponseEntity<User>> future = template.getForEntity("http://localhost:8080/userController/getUser",User.class);
//处理服务器端响应的异步回调方法
future.addCallback(new ListenableFutrueCallback<ResponseEntity<User>>(){
@Override
public void onSuccess(ResponseEntity<User> result){
System.out.println("客户端获取返回值:"+result.getBody());
}
@Override
public void onFailure(Throwable t){
System.out.println("客户端异常:"+t);
}
});
System.out.println("运行结束");
}
AsyncRestTemplate默认使用SimpleClientHttpRequestFactory进行HTTP操作,其底层通过java.net.HttpURLConnection实现。也可以使用其他的实现方式,如template.setAsyncRequestFactory(new HttpComponentsAsyncClientHttpRequestFactory())语句将使用Apache的http components作为底层访问组件。