本文主要介绍
Spring
中一些常见注解的部分属性配置介绍以及一些不常用注解的简单介绍。下面让我们直接进入主题吧。
@RequestMapping
@RequestMapping
可以说是
SpringMVC
以及
OpenFeign
中最常用的注解,其主要用于映射
Web
请求。
produces属性配置
当前主流服务大部分都是使用
JSON
作为数据交换格式,即通过配置
MappingJackson2HttpMessageConverter
或者
GsonHttpMessageConverter
定义数据交换时使用
JSON
进行格式转换。这时候默认的响应数据格式就是
application/json
,如果想要让
RequestMapping
请求返回
text/html
或者其他非
application/json
数据。那么
RequestMapping#produces
就可以派上用场了。
produces
属性配置可以调整数据响应格式,比如下面这段代码:
Hello World!
\n" +
" \n" +
"\n";
}
produces属性调整数据响应格式
这时候请求该页面返回的数据格式就是
text/html;charset=UTF-8
了。如果我们不添加
produces
配置,那么由于我们也配置了
StringHttpMessageConverter
,并且配置的
StringHttpMessageConverter
执行顺序早于
MappingJackson2HttpMessageConverter
等
JSON
消息转换器,那么这时候返回的数据格式就是
text/plain;charset=UTF-8
。具体看各自应用的消息转换器配置情况。
consumes属性配置
既然有
produces
属性可以配置数据的响应格式,那么当然也有对应的
consumes
配置用来限定请求映射的数据格式。如下面这段代码:
这里我们定义了两个同样的请求映射
/htmlReq
,其中一个通过
consumes
限定了请求映射的数据格式必须是
text/html
,另一个不限定数据映射格式。
限定请求映射的数据格式为html
不限定请求映射的数据格式
可以看到请求的数据格式如果是
text/html
,那么将会被映射到
htmlReq
方法。其他格式则被映射到
htmlReqNoConsumes
方法。
produces
和
consumes
属性通常用于与外部的对接,使用频率较低,有时候外部对接文档不完善,这时候我们就要通过直接发送请求确认他们的请求响应数据格式要求,然后相应的使用
produces
和
consumes
进行调整。
派生注解
说到
@RequestMapping
,就不得不提及它的派生注解:
@GetMapping
、
@PostMapping
、
@DeleteMapping
等注解。这些注解首先都标注了
@RequestMapping
,即他们本身都是
@RequestMapping
注解,然后通过
@AliasFor
注解将注解的属性别名映射到
@RequestMapping
的属性上。最后使用的使用通过
AnnotationUtils
和
AnnotatedElementUtils
进行别名配置合并或者同义化处理,注意派生注解在
Spring
框架注解中用的相当多,我们可以通过派生注解的方法进一步增强
@RequestMapping
,比如添加版本号映射功能等。这些后续有机会再讲。
@Ordered 和 @Priority
@Ordered
注解和
@Priority
注解以及
org.springframework.core.Ordered
接口都可以定义
Bean
的实例化顺序,同时
Spring
提供了
org.springframework.core.annotation.AnnotationAwareOrderComparator
工具类让我们可以对特定的
Bean
数组或者列表依照从小到大进行排序。如下代码:
那么启动容器后,通过
AnnotationAwareOrderComparator#sort
方法排序所有
XxHandler
实例的时候,将能够得到
ACBD
处理器有序列表。
通过@Order和@Priority以及Ordered控制排序
@EnableAutoConfiguration
@EnableAutoConfiguration
注解用于激活
Spring
的自动配置,在
SpringBoot
项目可能看得比较少,因为实际上该注解已经默认组合到
@SpringBootApplication
注解了。该注解的主要作用简单理解就是搜索所有
classpath
路径下的
META-INF/spring.factories
配置文件中的
org.springframework.boot.autoconfigure.EnableAutoConfiguration
配置项中定义的类完全限定名,然后将这些类统一作为配置类交给
Spring
进行自动配置。搜索可以发现
classpath
下有很多的
spring.factories
配置文件:
SpringFactories属性配置文件
spring.factories
配置文件的
org.springframework.boot.autoconfigure.EnableAutoConfiguration
配置项是自定义
SpringBootStarter
的核心,通过该配置项和
@EnableAutoConfiguration
我们可以实现高度可插拔的
SpringBootStarter
,这个有机会可以另外开篇讲解。
@Import
@Import
注解是一个比较有趣的注解,它既可以自由选择需要加载的配置类,也可以高度自由地定义
Bean
的注册。
它只有一个必填属性
value
,具体有三种用法:
导入配置类
这种方法导入的类通常标注有
@Configuration
,当然这不是硬性要求。比如
Druid
的数据源自动配置:
选择性加载配置类
这种方式导入的类必须实现
org.springframework.context.annotation.ImportSelector
接口,通过该接口的
selectImports(AnnotationMetadata importingClassMetadata)
方法确定导入的配置类。比如:
@CacheAutoConfiguration
。
动态注册Bean
这种方式导入的类必须实现
org.springframework.context.annotation.ImportBeanDefinitionRegistrar
接口,通过
registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
方法动态注册
SpringBean
。比如:
MyBatis
的
@MapperScan
注解导入的
MapperScannerRegistrar
。是自
@Import
通常会结合
@EnableXxx
(
Spring
的自动配置类)注解使用。算是自动化配置的一个核心类。
@Role
这个注解应该说大部分人没见过,即使见过应该也不会用到。这个注解主要用户标注
SpringBean
的角色。总共有三种角色:
ROLE_APPLICATION
简单理解就是这个
Bean
属于用户,是应用大部分
Bean
的角色。通常我们的
Bean
默认就是这种。
ROLE_SUPPORT
指示
Bean
同样属于用户,但是一般是外部配置的比较复杂的
Bean
。
ROLE_INFRASTRUCTURE
指示
Bean
不属于用户,属于
Spring
内部的基础设施
Bean
,通常给
Spring
内部工作使用。
这个注解在高度自定义校验器(抽离成独立依赖并提供给其他服务集成使用,而不是在各个应用中单独配置)的时候会用到,如果你自己注册到
Spring
的
LocalValidatorFactoryBean
没有添加
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
注解,那么运行时将直接报错。默认的
ValidationAutoConfiguration
自动配置如下:
目前该角色的
Bean
主要由
org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator
进行判断是否生成自动代理切面。
限于篇幅原因,本文不少注解没有实例讲解,后续有机会我们会单独开篇讲解。如有勘误,欢迎斧正!