[一知半解,就是给自己挖坑]
--------------------------------------------------------------------------------------------------------------------------------------------------------
清单:18:@InitBinder
在实际操作中经常会碰到表单中的日期 字符串和Javabean中的日期类型的属性自动转换, 而springMVC默认不支持这个格式的转换,所以必须要手动配置, 自定义数据类型的绑定才能实现这个功能。解决的办法就是使用spring mvc提供的@InitBinder标签。
示例代码:
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
}
注意被标注 @InitBinder 注解的方法必须拥有一个 WebDataBinder 类型的入参,以便 Spring MVC 框架将注册属性编辑器的 WebDataBinder 对象传递进来。
-------------------------------------------------------------------------------------------------------------------------------------
清单:19:@Value
作用:在代码中注入*.properties文件中的数据。
示例代码--步骤1:
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:/config/*.properties</value>
</list>
</property>
</bean>
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
<property name="properties" ref="configProperties" />
</bean>
示例代码--步骤2:
建立配置文件内容:
userPageSize=5
示例代码--步骤3:
在Controller中使用注解获得配置项内容:
@Value("#{configProperties['userPageSize']}")
private String userPageSize;
后面的代码就可以使用userPageSize这个私有变量了,这个字符串的值就是我们配置文件中配置的5.
特别的:给大家推荐一篇文章《@Value注入Properties 使用错误的案例》
------------------------------------------------------------------------------------------------------------------------------------------------------
清单:20:@RestController
为了方便Rest开发,Spring 4.0重要的一个新的改进是@RestController注解,它继承自@Controller注解。4.0之前的版本,Spring MVC的组件都使用@Controller来标识当前类是一个控制器servlet。在Controller上标注了@RestController,这样相当于Controller的所有方法都标注了@ResponseBody,这样就不需要在每个@RequestMapping方法上加 @ResponseBody了。
示例代码:
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/test")
public User view() {
User user = new User();
user.setId(1L);
user.setName("haha");
return user;
}
@RequestMapping("/test2")
public String view2() {
return "{\"id\" : 1}";
}
}
添加了一个
AsyncRestTemplate
,支持REST客户端的异步无阻塞支持。
示例代码:
@RestController
public class UserController {
private UserService userService;
@Autowired
public UserController(UserService userService) {
this.userService = userService;
}
@RequestMapping("/api")
public Callable<User> api() {
System.out.println("=====hello");
return new Callable<User>() {
@Override
public User call() throws Exception {
Thread.sleep(10L * 1000); //暂停两秒
User user = new User();
user.setId(1L);
user.setName("haha");
return user;
}
};
}
}
测试程序:
public static void main(String[] args) {
AsyncRestTemplate template = new AsyncRestTemplate();
//调用完后立即返回(没有阻塞)
ListenableFuture<ResponseEntity<User>> future = template.getForEntity("http://localhost:9080/spring4/api", User.class);
//设置异步回调
future.addCallback(new ListenableFutureCallback<ResponseEntity<User>>() {
@Override
public void onSuccess(ResponseEntity<User> result) {
System.out.println("======client get result : " + result.getBody());
}
@Override
public void onFailure(Throwable t) {
System.out.println("======client failure : " + t);
}
});
System.out.println("==no wait");
}
此处使用Future来完成非阻塞,这样的话我们也需要给它一个回调接口来拿结果; Future和Callable是一对,一个消费结果,一个产生结果。调用完模板后会立即返回,不会阻塞;有结果时会调用其回调。
AsyncRestTemplate默认使用SimpleClientHttpRequestFactory,即通过java.net.HttpURLConnection实现;另外我们也可以使用apache的http components;使用template.setAsyncRequestFactory(new HttpComponentsAsyncClientHttpRequestFactory());设置即可。
-------------------------------------------------------------------------------------------------------------------------------------
至此, 白话Spring(中级篇)---注解系列结束,在此特别感谢各位世界的大神,感激感激!
这个我们仅仅举出对部分内容解释并举例,更多内容请读者参考官方文档。如有问题欢迎探讨!
参考资料:
https://spring.io/guides/gs/spring-boot/
http://blog.csdn.net/white__cat/article/details/42103155
http://blog.csdn.net/yangxt/article/details/19971269