spring,spring boot ,spring cloud使用小技巧杂记(持续更新)

1. 自带基于Order的比较器OrderComparator

一个类如果实现OrderedPriorityOrdered类,在升序排序的时候则可以直接使用
Collections.sort(list, OrderComparator.INSTANCE);,实现PriorityOrdered接口的优先级大于Ordered
AnnotationAwareOrderComparator.sort(list)则支持@Order注解和@Priority注解

2. 泛型List<T> ,Map<String,T> 自动注入

如下:

    在某个配置类中有如下配置
    @Configuration
    public class MyConfig{
        @Bean("filterA")
        public IFilter  filterA(){
            return new FilterA();
        }
        @Bean("filterB")
        public IFilter  filterB(){
            return new FilterB();
        }
    }
    在其他类中采用如下方式注入则可以获取所有实现类
    @Autowired
    private List<IFilter> filterList;//所有实现类的bean
    @Autowired
    private IFilter[]  filterArr;
    @Autowired
    private Map<String, IFilter> filterMap;

spring 还是默默的帮我们做了很多事

3. ObjectProvider使用

一次排查问题看到如下源码,好奇的查了一下ObjectProvider

protected static class DispatcherServletRegistrationConfiguration {

		@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
		@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
		public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,
				WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) {
			DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet,
					webMvcProperties.getServlet().getPath());
			registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
			registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
			multipartConfig.ifAvailable(registration::setMultipartConfig);
			return registration;
		}

	}

ObjectProvide接口使用场景:

  1. 如果注入实例为空时,使用ObjectProvider则会延迟注入(感觉跟@Resource注解功能有点像)避免了强依赖导致的依赖对象不存在异常
  2. 如果有多个实例,ObjectProvider的方法会根据Bean实现的Ordered接口或@Order注解指定的先后顺序获取一个Bean

4. spring mvc扩展点

4.1. ResponseBodyAdvice 统一处理返回值或返回体

可以借助@ControllerAdvice,ResponseBodyAdvice 统一处理返回值或返回体

@ControllerAdvice(basePackages = "com.xxx.xxx")
@Order(0)
public class MyBodyAdvice implements ResponseBodyAdvice<Object> {

	Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
	    //可以通过方法名、转换器来判断要不要拦截返回
	    //return PageInfo.class.isAssignableFrom(returnType.getParameterType();
	    //returnType.getMethod().getName()、returnType.getMethod().getAnnotation(ExcludeBodyAdvice.class)
	    return  MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
	    
	}

	@Override
	public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
			ServerHttpResponse response) {

		ResultInfo<?> reslutInfo=(ResultInfo<?>) returnValue;
        //统一修改或新增返回值/响应体
        reslutInfo.setXXX("xxx");
        //返回修改后的值
        return msg;
	}

4.2. HandlerMethodArgumentResolver 统一处理请求参数

如下将登录的信息直接绑定到入参中

 public class LoginUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
 @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(User.class)
                && parameter.hasParameterAnnotation(LoginUserParam.class);
    }
 
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
        return  (User) webRequest.getAttribute(Consts.CURRENT_USER, RequestAttributes.SCOPE_REQUEST);
}

4.3. HandlerExceptionResolver 统一异常处理

spring mvc常用的统一异常的处理方式:

  1. 自定义类继承HandlerExceptionResolver
  2. 使用@ControllerAdvice@ExceptionHandler配合使用
    使用见《@ExceptionHandler or HandlerExceptionResolver》

5 Duration 配置

之前针对时间间隔的配置,如下:

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
	private int timeout;
}

对应的yml文件:

spring:
  redis:
    timeout: 5000 #单位毫秒

如果没有注解,则根本不知道单位是啥。
jdk1.8引入Duration后 ,

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
	/**
	 * Connection timeout.
	 */
	private Duration timeout;
}
long timeHours = timeout.toHours();//小时
long timeMinutes = timeout.toMinutes();//分钟
long timeMillis = timeout.toMillis();//毫秒
long timeNanos = timeout.toNanos();//纳秒

对应的yml文件:

spring:
  redis:
  	#如1s,1m,2h,5d
    timeout: 5s
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值