如何编写一个简单的spring-boot-starter

如何编写一个简单的spring-boot-starter

Scroll Down

编写一个简单的spring-boot-starter

自动配置

  1. 首先需要引入两个包:
    1.1 引入spring-boot-autoconfigure以实现自动配置
    1.2 引入spring-boot-configuration-processor包,以生成自定义配置的提示

  2. 编写配置类,并加上@Configuration注解声明配置类

  3. 在resources的META-INF文件夹下spring.factories文件,指定需要生效的配置类,多个类用逗号隔开:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=需要生效类的全路径
  1. 编写Properties类,声明可配置属性,并使用@Component@ConfigurationProperties(prefix = "myProp")注解, 若属性为其他配置对象,可使用@NestedConfigurationProperty
  2. 在配置类上使用@EnableConfigurationProperties(Properties.class)启用properties类
  3. 条件配置:
    1. @Conditional系列注解,可自定义配置使其在特定情况下才生效。
    2. @Primary注解可在有多个同类型的bean的情况下,优先选择含有该注解的bean

自定义注解

Spring提供的注解工具类:AnnotatedElementUtilsAnnotationUtils

bean生命周期及钩子函数

InstantiationAwareBeanPostProcessor继承于BeanPostProcessor,其中有5个方法:

Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName);

boolean postProcessAfterInstantiation(Object bean, String beanName);

PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName);

Object postProcessBeforeInitialization(Object bean, String beanName);

Object postProcessAfterInitialization(Object bean, String beanName);

定制控制器

轻量级定制化

RequestBodyAdvice

public interface RequestBodyAdvice {

	boolean supports(MethodParameter methodParameter, Type targetType,
			Class<? extends HttpMessageConverter<?>> converterType);

	HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
			Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;

  
	Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
			Type targetType, Class<? extends HttpMessageConverter<?>> converterType);

  
	@Nullable
	Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter,
			Type targetType, Class<? extends HttpMessageConverter<?>> converterType);


}

ResponseBodyAdvice

public interface ResponseBodyAdvice<T> {

	boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
  
  
	@Nullable
	T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
			Class<? extends HttpMessageConverter<?>> selectedConverterType,
			ServerHttpRequest request, ServerHttpResponse response);

}

重量级定制化

可实现HandlerMethodArgumentResolver接口,自定义参数注入

public interface HandlerMethodArgumentResolver {

	boolean supportsParameter(MethodParameter parameter);

	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

可实现HandlerMethodReturnValueHandler接口,自定义返回值

public interface HandlerMethodReturnValueHandler {

	boolean supportsReturnType(MethodParameter returnType);

	void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
			ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;

}

HttpMessageConverter<T>接口

public interface HttpMessageConverter<T> {

	boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);

	boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);

	List<MediaType> getSupportedMediaTypes();

	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;

	void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;

}