Spring Boot使用过程中,经常需要和很多注解打交道。也是我们常说的注解编程。所以接下来我们对Spring Boot常用注解做一个简单的收集。
一 配置类相关注解
配置类相关注解 | 解释 |
---|---|
@SpringBootApplication | 组合注解,由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三者组成,我们一般把该注解添加在启动类上 |
@ComponentScan | 用于指定组件的扫描路径和过滤规则 |
@EnableAutoConfiguration | 启用自动配置,就是让@SpringBootConfiguration、@Configuration注解起作用 |
@SpringBootConfiguration | 标注当前类是配置类 |
@Configuration | 标注当前类是配置类 |
@Bean | 注解在方法上,一般在@Configuration注解类下使用,把方法返回的对象添加到Spring IOC容器里面去,并且容器里面Bean的名字就是方法名 |
@Import | 导入类,有时没有把某个类注入到IOC容器中,但在运用的时候需要获取该类对应的Bean,这个时候我们就可以使用@Import导入需要的Bean |
@AutoConfigureAfter | 加载指定配置的类之后再加载当前类,一般和@Configuration一起出现 |
@AutoConfigureBefore | 加载指定配置的类之前加载当前类,一般和@Configuration一起出现 |
@AutoConfigureOrder | 指定配置类的加载顺序,一般和@Configuration一起出现 |
1.1 @SpringBootApplication
@Target(ElementType.TYPE) // 添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //@SpringBootConfiguration
@EnableAutoConfiguration // @EnableAutoConfiguration
@ComponentScan(excludeFilters = { // @ComponentScan
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
/**
* 排除特定的自动配置类 -- @EnableAutoConfiguration里面的功能
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
/**
* 排除特定的自动配置类名称 -- @EnableAutoConfiguration里面的功能
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
/**
*
* 在指定的包下扫描带组件注解的类 -- @ComponentScan里面的功能
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
/**
* 指定类,会去扫描该类所在的包下面带有组件注解的类 -- @ComponentScan里面的功能
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
@SpringBootApplication是一个组合注解,由@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解组成.换言之加了@SpringBootApplication注解之后就把相应的三个注解的功能都加上了。Springboot提供了。简化程序的配置。@SpringBootApplication注解一般添加的启动了上。关于@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan我们会在下面讲到。
1.2 @ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 可以添加在类上
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* scan对应的包路径(可以指定多个)
*/
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
/**
* 可以指定多个类或接口的class,扫描时会 在这些指定的类和接口所属的包进行扫面。
*/
Class<?>[] basePackageClasses() default {};
/**
* 通过BeanNameGenerator来得到bean对应的名字,进而得到对应的Class
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* 处理检测到的bean的scope范围
*/
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
/**
* 是否为检测到的组件生成代理
*/
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
/**
* 控制符合组件检测条件的类文件 默认是包扫描下的(包括子包) *.class
*/
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
/**
* 是否对带有@Component @Repository @Service @Controller注解的类开启检测,默认是开启的
*/
boolean useDefaultFilters() default true;
/**
* 指定某些定义Filter满足条件的组件 FilterType有5种类型如:
* ANNOTATION, 注解类型 默认
* ASSIGNABLE_TYPE,指定固定类
* ASPECTJ, ASPECTJ类型
* REGEX,正则表达式
* CUSTOM,自定义类型
*
*/
Filter[] includeFilters() default {};
/**
* 排除某些过来器扫描到的类
*/
Filter[] excludeFilters() default {};
/**
* 扫描到的类是都开启懒加载 ,默认是不开启的
*/
boolean lazyInit() default false;
}
@ComponentScan做的事情就是告诉Spring从哪里找到Bean。@ComponentScan会默认去@SpringBootApplication注解的类所在的包及其下级包去扫描bean(就是去扫描添加了@Component、@Service、@Repository、@Controller),然后把他们添加到Spring IOC容器里面去。但是,有的时候有些包不在这个下面,这个时候我们就需要通过@ComponentScan显示的去指定要扫描的包名了。
1.3 @EnableAutoConfiguration、@SpringBootConfiguration、@Configuration
因为@EnableAutoConfiguration、@SpringBootConfiguration、@Configuration这三是一体的,所以咱们把他们归到一起来说明。
1.3.1 @EnableAutoConfiguration
@Target(ElementType.TYPE) // 组件添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* 排除特定的自动配置类
*/
Class<?>[] exclude() default {};
/**
*
* 排除特定的自动配置类名称
*/
String[] excludeName() default {};
}
@EnableAutoConfiguration注解使自动配置生效。用于帮助SpringBoot应用将所有符合条件的@SpringBootConfiguration、@Configuration配置加载到当前SpringBoot IOC容器里面去。换句话说,想使用@SpringBootConfiguration、@Configuration就得一定得使用@EnableAutoConfiguration注解。只有@EnableAutoConfiguration配合@SpringBootConfiguration、@Configuration共同作用下,才可以帮助Spring Boot把@SpringBootConfiguration、@Configuration修饰的类里面的Bean扫描出来,添加到Spring IOC容器里面去.
按照我们常规的Spring Boot应用。我们一般会启动类上添加@SpringBootApplication注解。其实就已经加上了@EnableAutoConfiguration注解,因为@SpringBootApplication注解包括了@EnableAutoConfiguration注解。
1.3.2 @SpringBootConfiguration、@Configuration
@SpringBootConfiguration、@Configuration两个注解是一样的。用来标记配置类。
@SpringBootConfiguration
@Target(ElementType.TYPE) // 添加在类上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration
@Target(ElementType.TYPE) // 添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 也是一个组件
public @interface Configuration {
/**
* Configuration注解的类也是一个组件,用于显示的指定在Spring容器里面组件的名称。
* 如果没有显示指定就是类的名称并且首字母小写
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
简单来说就是用@SpringBootConfiguration、@Configuration标注的类是配置类,同时在该类下面一般会包含一个或多个被@Bean注解的方法。这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描。加入到Spring IOC容器中。并且这些Bean的名称就是方法名。
1.4 @Bean
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) // 一般添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
/**
* 显示指定Bean对应的名字,如果没有指定则是对应的方法名字
*/
@AliasFor("name")
String[] value() default {};
/**
* 显示指定Bean对应的名字,如果没有指定则是对应的方法名字
*/
@AliasFor("value")
String[] name() default {};
@Deprecated
Autowire autowire() default Autowire.NO;
/**
* 用来表示当前bean是否可以被注入到其他实例中,依赖注入
*/
boolean autowireCandidate() default true;
/**
* 构造方法执行完之后,执行的方法
*/
String initMethod() default "";
/**
* 关闭应用程序上下文时在bean实例上调用的方法的可选名称
*/
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}
@Bean是一个方法级别上的注解,主要用在@SpringBootConfiguration、@Configuration注解的配置类里面使用。Spring Boot会帮助把@Bean注解方法的对象添加到Spring IOC容器里面去,供我们在别的地方使用。
1.4 @Import
@Target(ElementType.TYPE) // 指明该注解是添加在类上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* 需要import的类
*/
Class<?>[] value();
}
@Import注解用于帮助把我们需要的类导入到组件类里面去,有时没有把某个类注入到Spring IOC容器中,但在某个类使用的时候需要获取该类对应的Bean,此时就需要用到@Import注解。
1.5 控制配置类的加载顺序(@AutoConfigureAfter、@AutoConfigureBefore、@AutoConfigureOrder)
@AutoConfigureAfter、@AutoConfigureBefore
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE }) // 一般用于添加在类上
@Documented
public @interface AutoConfigureAfter {
/**
* Class数组对应的类加载之后在加载
*/
Class<?>[] value() default {};
/**
* 配置名称对应的配置类加载之后在加载
*/
String[] name() default {};
}
@AutoConfigureOrder
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
@Documented
public @interface AutoConfigureOrder {
int DEFAULT_ORDER = 0;
/**
* 加载顺序,值越小越先加载
*/
int value() default DEFAULT_ORDER;
}
@AutoConfigureAfter、@AutoConfigureBefore、@AutoConfigureOrder三个注解用于控制配置类的加载顺序。而且非常重要的一点是这三个注解一定要配合spring.factory文件来一起使用,因为Spring只会对spring.factory文件下的配置类进行排序。所以我们需要在resources/META-INF/spring.factory文件里面写入需要排序的这些配置类的路径。
二 Bean(组件)相关注解
2.1 申明Bean相关的注解
用于把一个类声明为Bean(组件)。这样Spring Boot启动的时候(注意@ComponentScan注解的使用)就会把这些Bean扫描出来添加到IOC容器里面去。
申明Bean相关的注解 | 解释 |
---|---|
@Component | 最普通的组件,可以被注入到Spring容器进行管理,通用注解 |
@Service | 作用于业务逻辑层的组件,只是标注该类处于业务逻辑层 |
@Repository | 作用于持久层(dao)的组件,并支持自动处理数据库操作产生的异常 |
@Component、@Service、@Repository注解属性都是一样的
@Target(ElementType.TYPE) //该注解一般用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* 组件对应的名字(获取组件的时候可以通过类型获取,也可以通过名字获取)
*/
String value() default "";
}
关于@Repository的作用,这里特别说明下。因为原生java操作数据库所产生的异常只定义了几种,但是产生数据库异常的原因却有很多种,这样对于数据库操作的报错排查造成了一定的影响;而Spring拓展了原生的持久层异常,针对不同的产生原因有了更多的异常进行描述。所以,在注解了@Repository的类上如果数据库操作中抛出了异常,就能对其进行处理,转而抛出的是翻译后的spring专属数据库异常,方便我们对异常进行排查处理。
关于@Component、@Service、@Repository的使用,最终只有一个目的,希望咱们一看到@Repository就知道这个是数据库Dao层的代码,一看到@Service注解就知道是业务层的代码。
2.2 Bean属性相关注解
Bean属性相关注解 | 解释 |
---|---|
@Scope | 设置Spring容器如何新建Bean实例,一般配合@Bean、@Component、@Service、@Repository一起使用 |
@PostConstruct | 在构造函数执行完之后执行 |
@PreDestory | 在Bean销毁之前执行 |
2.2.1 @Scope
@Target({ElementType.TYPE, ElementType.METHOD}) // 一般用来添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
/**
* Alias for {@link #scopeName}.
* @see #scopeName
*/
@AliasFor("scopeName")
String value() default "";
/**
*
* 指定要用于带注释的组件/ bean的作用域的名称
* 可以设置下面四种值
* - ConfigurableBeanFactory.SCOPE_PROTOTYPE: 每次依赖注入时,都会产生新的对象
* - ConfigurableBeanFactory.SCOPE_SINGLETON: 单例模式,在整个应用中只能创建一个实例
* - org.springframework.web.context.WebApplicationContext.SCOPE_REQUEST: 在一个请求中创建一个实例
* - org.springframework.web.context.WebApplicationContext.SCOPE_SESSION: 每次创建一个会话中创建一个实例
*/
@AliasFor("value")
String scopeName() default "";
/**
* 指定是否应将组件配置为作用域代理
* 可以设置为下面几种值
* - ScopedProxyMode.DEFAULT:等同于ScopedProxyMode.NO
* - ScopedProxyMode.NO:(默认)不进行代理
* - ScopedProxyMode.INTERFACES:创建一个JDK代理模式
* - ScopedProxyMode.TARGET_CLASS:基于类的代理模式
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
Scope字面意思是范围,标志一个注入器/对象的使用范围,很多文章说成生命周期也是可以的。比如,单例模式,局部单例模式等等。@Scope注解就是用来声明一个Bean的生命周期(作用域)。
@Scope实际使用的时候一般是添加在@Bean修饰的方法上的。比如如下的实例。
@Configuration
public class ZkConfiguration {
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) // 只有一个实例
@Bean(initMethod = "init", destroyMethod = "stop")
public ZkClient zkClient() {
return new ZkClient();
}
}
2.2.2 @PostConstruct
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@PostConstruct用来修饰一个分静态并且返回void的方法。该方法只会在构造函数之后执行一次。@PostConstruct一般@Component、@Service、@Repository修饰的对象里面使用。
2.2.3 @PreDestory
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@PreDestroy也是用来修饰一个分静态并且返回void的方法。该方法只会在对象函数之后执行一次。@PreDestory和一样@PostConstruct一般也是在@Component、@Service、@Repository修饰的对象里面使用。
2.3 Bean注入相关注解
注入注解就是帮助我们自动引入依赖的对象。
Bean注入相关注解 | 解释 |
---|---|
@Autowired | 先按类型注入,然后按照名称注入,都无法找到唯一的一个实现类则报错 |
@Inject | 在Spring的环境下,@Inject和@Autowired是相同的 |
@Resource | 先按名字注入,再按类型注入,都无法找到唯一的一个出现异常 |
@Qualifier | 用于指定Bean的名字,一般配合用来配合@Autowired使用 |
2.3.1 @Autowired
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* 申明当前对象是否是必须的
*/
boolean required() default true;
}
@Autowired Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入Bean。它可以对类成员变量、方法及构造函数进行标注。 通过 @Autowired的使用来消除 set ,get方法。@Autowired先通过类型去Spring IOC容器里面查找对象,如果没有查找到再按照Bean名称去查找。如果无法找到唯一的Bean并且Bean是必须的则抛出异常。(可以看下@Qualifier的用法)
2.3.2 @Inject
在Spring的环境下,@Inject和@Autowired是相同的。
2.3.3 @Resource
@Target({TYPE, FIELD, METHOD}) // 添加在变量或者方法上
@Retention(RUNTIME)
public @interface Resource {
/**
* 资源的JNDI名称
*/
String name() default "";
/**
* 引用指向它的资源的名称可以使用全局JNDI名称链接到任何兼容的资源
*/
String lookup() default "";
/**
* Bean对应的类型
*/
Class<?> type() default java.lang.Object.class;
/**
* 资源的两种可能的身份验证类型
*/
enum AuthenticationType {
CONTAINER,
APPLICATION
}
/**
* 用于此资源的身份验证类型。
*/
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
/**
* 指示是否可以在此组件与其他组件之间共享此资源。
*/
boolean shareable() default true;
/**
* 此资源应映射到的产品特定名称
*/
String mappedName() default "";
/**
* 此资源的描述
*/
String description() default "";
}
@Resource有两个重要属性:name、type。@Resource和@Autowired的区别在于。@Resource先通过Bean名字去容器里面查找,如果没找到在通过类型去容器里面查找。
2.3.4 @Qualifier
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
/**
* 注解对应的名字
*/
String value() default "";
}
可能会有这样一种情况,当你创建多个具有相同类型的 bean 时,并且想要用一个属性只为它们其中的一个进行装配,在这种情况下,我们可以使用@Qualifier注释和@Autowired注释通过指定哪一个真正的bean将会被装配来消除混乱。比如如下的代码。
private ProductInfo productInfo;
@Autowired
@Qualifier(value = "productInfo")
public void setProductInfo(ProductInfo productInfo) {
this.productInfo = productInfo;
}
2.4 Bean延时加载注解(@Lazy)
@Lazy
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
/**
* 是否懒加载
*/
boolean value() default true;
}
@Lazy:用于标识Bean是否需要延迟加载,延时加载就是在第一次使用的时候才加载。@Lazy的主要作用就是用来减少Spring IOC容器启动的加载时间。
2.5 Bean依赖注解(@DependsOn)
@DependsOn
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
/**
* 依赖的Bean对应的名称
*/
String[] value() default {};
}
@DependsOn:控制Bean加载顺序。指定先加载@DependsOn对应的Bean。
三 读取配置文件(.properties、.yam)相关注解
读取配置文件相关的注解,就是用来帮助我们获取到配置文件.properties、.yam里面信息的。
读取配置文件相关注解 | 解释 |
---|---|
@EnableConfigurationProperties | 让使用@ConfigurationProperties注解的类生效 |
@ConfigurationProperties | 读取配置文件的信息,并自动封装成实体类 |
@PropertySource | 指定的属性文件(只能加载*.properties文件,不能加载yaml文件)映射到对象 |
@ImportResource | 导入Spring的*.xml配置文件,让xml配置文件里面的内容生效 |
3.1 @EnableConfigurationProperties
@Target(ElementType.TYPE) // 添加在类上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties {
/**
* 对应于添加了@ConfigurationProperties的类,让他们生效
*/
Class<?>[] value() default {};
}
@EnableConfigurationProperties注解的作用是让使用@ConfigurationProperties注解的类生效。你可以通过在@EnableConfigurationProperties注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean的定义。而且@EnableConfigurationProperties我们一般添加在Applicaiton类上面。
3.2 @ConfigurationProperties
@Target({ ElementType.TYPE, ElementType.METHOD }) // 添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
/**
* 属性前缀
*/
@AliasFor("prefix")
String value() default "";
@AliasFor("value")
String prefix() default "";
/**
* 是否忽视无效的字段
*/
boolean ignoreInvalidFields() default false;
/**
* 是否忽视未知字段
*/
boolean ignoreUnknownFields() default true;
}
有时候有这样子的情景,我们想把配置文件的信息,读取并自动封装成实体类,这样子,这时候,我们就可以使用@ConfigurationProperties注解,它可以把同类的配置信息自动封装成实体类。
我们用一个简单的实例来说明,比如我们在application.yml里面添加一些自定义的属性。我们就可以通过@ConfigurationProperties注解来获取到这些属性值
application.yml文件里面添加
# 自定义的一些属性
user:
info:
name: tuacy
age: 27
把这些属性映射到实体类
@ConfigurationProperties(prefix = "user.info")
public class UserInfo {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
最后在Application类上添加@EnableConfigurationProperties(value = {UserInfo.class})。这样就把配置文件里面的数据都映射到UserInfo类上去了,并且UserInfo类已经添加到了Spring IOC容器里面去了。
3.3 @PropertySource
@Target(ElementType.TYPE) // 该注解添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
/**
* 指示此属性源的名称。如果省略,将根据底层资源的描述生成名称
*/
String name() default "";
/**
* 指示要加载的属性文件的资源位置
* 例如,value = "classpath:product.properties"。则表示resource目录下的product.properties文件
*/
String[] value();
/**
* 指示是否应忽略找不到属性资源的错误
*/
boolean ignoreResourceNotFound() default false;
/**
* 编码格式
* 例如,"UTF-8"
*/
String encoding() default "";
/**
* 只是怎么去解析属性对应的值,比如如果想把 yyyy-mm 转换成Date
* @see org.springframework.core.io.support.DefaultPropertySourceFactory
* @see org.springframework.core.io.support.ResourcePropertySource
*/
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
@PropertySource注解的作用是加载指定的属性文件(配置文件),把配置文件映射到对象。只能加载*.properties文件,不能加载yaml文件。@PropertySource一般配合@Value一起使用。
关于@PropertySource注解使用的一个简单的实例。
resource目录下product.properties文件内容(配置文件)
# 自定义配置信息
ppid = 1000
mmid = 1
ccid = 10
配置文件映射到Bean
/**
* 注入resource下product.properties文件里面的信息
*/
@Configuration
@PropertySource(value = "classpath:product.properties", encoding = "utf-8")
public class ProductInfo {
@Value("${ppid}")
private int pid;
@Value("${mmid}")
private int mid;
@Value("${ccid}")
private int cid;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
}
3.4 @ImportResource
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 该注解只能添加在类上(我们一般把他添加在主配置类上)
@Documented
public @interface ImportResource {
/**
* xml配置文件对应的位置
*/
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
/**
*
* 处理通过属性指定的资源时使用的实现
*/
Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;
}
导入Spring的xml配置文件,让xml配置文件里面的内容生效。SpringBoot中编写的Spring配置文件是不能自动识别的。(相当于把Bean放到xml配置文件里面去定义了。随着Spring Boot的使用这种方式会越来越少,因为现在大部分都是通过@Configuration来配置的)。
四 @Value注解
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
*
* 实际值表达式
* 例如,{@code #{systemProperties.myProp}}.
*/
String value();
}
@Value注解用于将外部的值动态注入到Bean中,大概有如下这么几种情况:
4.1 注入普通字符串
/**
* 注入普通字符串,相当于private String normal = "normal"
*/
@Value("normal")
private String normal;
4.2 注入操作系统属性
/**
* 注入操作系统属性
*/
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
4.3 注入表达式结果
/**
* 注入表达式结果,相当于 double randomNumber = java.lang.Math).random() * 100.0
*/
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
4.4 注入其他Bean属性
/**
* 注入其他Bean属性:相当于把IOC容器里面valueInject名字对应的对象的name属性赋值给变量
*/
@Value("#{valueInject.name}")
private String fromAnotherBean;
4.5 注入文件资源
/**
* 注入文件资源,相当于把resource目录下valueInjectConfig.txt文件注入进来
*/
@Value("classpath:valueInjectConfig.txt")
private Resource valueInjectConfig;
4.6 注入URL资源
/**
* 注入URL资源,相当于把http://www.baidu.com对应的资源注入进来
*/
@Value("http://www.baidu.com")
private Resource baiduUrl;
4.7 注入配置文件信息
比如如下的例子我们加载product.properties文件里面的信息(我们也可以加载application.yml文件里面的信息,加载application.yml文件信息的时候可以不加@PropertySource指定路径)
resource目录下product.properties文件信息
# 自定义配置信息
ppid = 1000
mmid = 1
ccid = 10
@Value注入
/**
* 注入resource下product.properties文件里面的信息
*/
@Configuration
@PropertySource(value = "classpath:product.properties", encoding = "utf-8")
public class ProductInfo {
@Value("${ppid}")
private int pid;
@Value("${mmid}")
private int mid;
@Value("${ccid}")
private int cid;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
}
五 环境切换相关注解
环境切换注解说白了就是做到不同的环境注入不同的Bean。比如常见的有开发环境和测试环境用的数据库配置不一样。
环境切换相关注解 | 解释 |
---|---|
@Profile | 通过设定Environment的ActiveProfiles来设定当前Bean是否要添加到Spring IOC容器里面去 |
@Conditional | 按照一定的条件进行判断,满足条件给添加到Spring IOC容器里面去 |
5.1 @Profiles
@Target({ElementType.TYPE, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
/**
* profile对应的名字。比如生成环境有一个名字,测试环境有一个名字
*/
String[] value();
}
@Profiles可以实现不同环境(开发、测试、部署等)使用不同的配置。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。
5.2 @Conditional
@Target({ElementType.TYPE, ElementType.METHOD}) // 常用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* 继承Condition接口的Class数组
* 当所有的Class的matches方法都返回true的时候,才满足条件
*/
Class<? extends Condition>[] value();
}
@Conditional注解会按照一定的条件进行判断,满足条件给容器注册bean。
六 条件注解
条件注解 | 解释 |
---|---|
@ConditionalOnClass | classpath中存在该类时起效 |
@ConditionalOnMissingClass | classpath中不存在该类时起效 |
@ConditionalOnBean | Spring IOC容器中存在该类型Bean时起效 |
@ConditionalOnMissingBean | Spring IOC容器中不存在该类型Bean时起效 |
@ConditionalOnSingleCandidate | DI容器中该类型Bean只有一个或@Primary的只有一个时起效 |
@ConditionalOnExpression | SpEL表达式结果为true时 |
@ConditionalOnProperty | 参数设置或者值一致时起效 |
@ConditionalOnResource | 指定的文件存在时起效 |
@ConditionalOnJndi | 指定的JNDI存在时起效 |
@ConditionalOnJava | 指定的Java版本存在时起效 |
@ConditionalOnWebApplication | Web应用环境下起效 |
@ConditionalOnNotWebApplication | 非Web应用环境下起效 |
所有的这些条件注解一般和声明Bean的一些注解(@Bean、@Component、@Service、@Repository)同时出现。来控制Bean是否生成。
七 切面AOP相关注解
切面AOP相关注解 | 解释 |
---|---|
@Aspect | 声明一个切面,只是一个标识作用 |
@PointCut | 声明切点,在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持 |
@Around | 在方法执行之前与之后执行 |
@Before | 在方法执行之前执行 |
@After | 在方法执行之后执行 |
@AfterReturning | 方法正常退出的时候执行 |
@AfterThrowing | 方法有异常抛出的时候执行 |
7.1 @Aspect
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 添加在方法上
public @interface Aspect {
/**
* @return the per clause expression, defaults to singleton aspect.
* Valid values are "" (singleton), "perthis(...)", etc
*/
public String value() default "";
}
@Aspect注解的作用是把当前类标识为一个切面供Spring容器读取。@Aspect注解只是一个标识作用。
7.2 @PointCut
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 添加在方法上面
public @interface Pointcut {
/**
* 切入点表达式
*/
String value() default "";
/**
* 指定命名切入点方法参数列表参数名字,
* 可以有多个用“,”分隔,这些参数将传递给通知方法同名的参数,
* 同时比如切入点表达式“args(param)”将匹配参数类型为命名切入点方法同名参数指定的参数类型。
*/
String argNames() default "";
}
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
7.3 @Around
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 注解用于添加在方法上
public @interface Around {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@Around环绕增强,方法执行前和执行后都会执行。
7.4 @Before
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@Before方法执行前执行。
7.5 @After
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@After方法执行后执行。
7.6 @AfterReturning
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterReturning {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value() default "";
/**
* 切入点表达式,一般配合@Pointcut一起使用,指定时覆盖 "value"
*/
String pointcut() default "";
/**
* 用于绑定返回值的参数的名称
*/
String returning() default "";
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@AfterReturning方法正常退出的时候执行。
7.7 @AfterThrowing
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterThrowing {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value() default "";
/**
* 切入点表达式,一般配合@Pointcut一起使用,指定时覆盖 "value"
*/
String pointcut() default "";
/**
* 用于绑定抛出异常的参数的名称
*/
String throwing() default "";
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@AfterThrowing方法抛出异常的时候执行。
八 事件监听注解(@EventListener)
@EventListener
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) // 添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
/**
* 此侦听器处理的事件类。具体可以参考ApplicationEvent的用法
*/
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
/**
* 用来定义所侦听事件是否处理的前置条件,这里需要注意的是使用 Spring Expression Language (SpEL)定义条件
* condition可以实现更加精细的事件监听
*
* 比如如下的例子,监听CustomEvent里面messageEntity对象的code的属性为‘oKong’的事件
* @EventListener(condition = "#customEvent.messageEntity.code == 'oKong'")
* public void handleCustomEventByCondition(CustomEvent customEvent) {
* //TODO:
* }
*/
String condition() default "";
}
@EventListener修饰在方法上。用于监听Spring事件。更加具体的用法可以参考ApplicationListener的使用。
七 异步注解
异步注解 | 解释 |
---|---|
@EnableAsync | 开启异步方法的支持 |
@Async | 异步方法 |
7.1 @EnableAsync
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
/**
* 指示要在类或方法级别检测的“异步”注释类型,默认是@Async
*/
Class<? extends Annotation> annotation() default Annotation.class;
/**
* 当AdviceModemode为PROXY时,选择代理是基于接口实现还是cglib实现
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK实现还是AspectJ实现
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的顺序
* 默认值是 Ordered.LOWEST_PRECEDENCE,为了在所有其他后处理器之后运行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
@EnableAsync用于开启异步方法的支持。只有开启了异步方法的支持才可以使用@Async。
7.2 @Async
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
/**
*
* 指定异步操作的限定符值。
*/
String value() default "";
}
@Async可以把某一个方法或者类下面的方法全部变成异步处理的方法。
八 定时任务相关注解
定时任务相关注解 | 解释 |
---|---|
@EnableScheduling | 在配置类上使用,开启计划任务的支持 |
@Scheduled | 来申明这是一个任务,包括cron,fixDelay,fixRate等类型 |
8.1 @EnableScheduling
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
@EnableScheduling注解用于开启定时任务的支持。简单来说就是如果我们想在应用里面使用@Scheduled就需要添加@EnableScheduling注解。一般添加在主配置类上。
8.2 @Scheduled
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
/**
* cron表达式
*/
String cron() default "";
/**
* 时区
* java.util.TimeZone#ID。cron表达式会基于该时区解析
*/
String zone() default "";
/**
* 上一次执行完毕时间点之后多长时间再执行
* @Scheduled(fixedDelay = 5000) //上一次执行完毕时间点之后5秒再执行
*/
long fixedDelay() default -1;
/**
* 与fixedDelay意思相同,只是使用字符串的形式。唯一不同的是支持占位符
* @Scheduled(fixedDelayString = "5000") //上一次执行完毕时间点之后5秒再执行
*/
String fixedDelayString() default "";
/**
* 上一次开始执行时间点之后多长时间再执行
* @Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行
*/
long fixedRate() default -1;
/**
* 与fixedRate意思相同,只是使用字符串的形式
*/
String fixedRateString() default "";
/**
* 第一次延迟多长时间后再执行
*/
long initialDelay() default -1;
/**
* 与initialDelay意思相同,只是使用字符串的形式
*/
String initialDelayString() default "";
}
@Scheduled用于定义一个定时任务。Spring会帮我们去解析这个定时任务,并且按照我们设置的时间去执行这个任务。
九 事务相关注解
事务相关注解 | 解释 |
---|---|
@EnableTransactionManagement | 开启注解式事务的支持 |
@Transactional | 控制事务注解 |
9.1 @EnableTransactionManagement
@Target(ElementType.TYPE) // 该注解用于添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* 当AdviceModemode为PROXY时,选择代理是基于接口实现还是cglib实现
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK实现还是AspectJ实现
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的顺序
* 默认值是 Ordered.LOWEST_PRECEDENCE,为了在所有其他后处理器之后运行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
@EnableTransactionManagement用于开启事务的支持,我们一般在主配置类上添加该注解。
9.2 @Transactional
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
*/
@AliasFor("transactionManager")
String value() default "";
/**
* 当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
*/
@AliasFor("value")
String transactionManager() default "";
/**
* 事务的传播行为,默认值为 REQUIRED
* 默认 Propagation.REQUIRED
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* 事务的隔离度,默认值采用 DEFAULT
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* 事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
/**
* 指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
*/
boolean readOnly() default false;
/**
* 用于指定能够触发事务回滚的异常类型,
*/
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
/**
* 抛出 no-rollback-for 指定的异常类型,不回滚事务。
*/
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
@Transactional注解我们一般添加在Dao层的方法上面。当数据库操作异常的时候回滚。
十 缓存相关注解
缓存相关注解 | 解释 |
---|---|
@EnableCaching | 开启缓存注解的支持 |
@CacheConfig | 用于统一制定一些配置参数,这样在其他缓存注解里面就不用重复指定 |
@Cacheable | 如果之前已经有缓存数据值直接返回缓存数据,否则执行方法,缓存方法的返回结果 |
@CachePut | 能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用 |
@CacheEvict | 能够根据一定的条件对缓存进行清空 |
@Caching | 组合多个Cache注解的使用 |
10.1 @EnableCaching
@Target(ElementType.TYPE) // 该注解一般用于添加类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
/**
* 当AdviceModemode为PROXY时,选择代理是基于接口实现还是cglib实现
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK实现还是AspectJ实现
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的顺序
* 默认值是 Ordered.LOWEST_PRECEDENCE,为了在所有其他后处理器之后运行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
@EnableCaching注解用于开启缓存的支持,只有开启了缓存的支持,才有后续的@Cacheable、@Caching、@CacheEvict、@CachePut、@CacheConfig的使用。
10.2 @CacheConfig
@Target(ElementType.TYPE) // 该注解常用于添加在类上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {
/**
* 缓存的名称,必须至少指定一个,我们可以简单的认为是命名空间。我们一般用项目的名字
*/
String[] cacheNames() default {};
/**
* key生成器,可以实现 org.springframework.cache.interceptor.KeyGenerator接口,来规定想要保存的key的格式
* 设置自定义的key生成器实现类对应Bean的名字
*/
String keyGenerator() default "";
/**
* 缓存管理器,我们可以实现CacheManager接口来实现缓存管理器
* 指定自定义的缓存管理器对应的Bean名称
*/
String cacheManager() default "";
/**
* Cache解析器,用于根据实际情况来动态解析使用哪个Cache,实现CacheResolver接口
* 指定自定义的Cache解析器对应的Bean名称
*/
String cacheResolver() default "";
}
当我们需要缓存的地方越来越多,这个时候我们可以使用@CacheConfig注解来统一制定一些参数。这样在@Cacheable、@CachePut等这些注解上就可以不用重复去填这些参数了。
10.3 @Cacheable
@Target({ElementType.METHOD, ElementType.TYPE}) // 该注解用于添加在方法或者类上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
/**
* 缓存的名称,必须至少指定一个,缓存的名称,必须至少指定一个,我们可以简单的认为是命名空间。我们一般用项目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 缓存的key
*/
String key() default "";
/**
* key生成器,可以实现 org.springframework.cache.interceptor.KeyGenerator接口,来规定想要保存的key的格式
* 设置自定义的key生成器实现类对应Bean的名字
*/
String keyGenerator() default "";
/**
* 缓存管理器,我们可以实现CacheManager接口来实现缓存管理器
* 指定自定义的缓存管理器对应的Bean名称
*/
String cacheManager() default "";
/**
* Cache解析器,用于根据实际情况来动态解析使用哪个Cache,实现CacheResolver接口
* 指定自定义的Cache解析器对应的Bean名称
*/
String cacheResolver() default "";
/**
* 缓存的条件
*/
String condition() default "";
/**
* 否定缓存。当条件结果为TRUE时,就不会缓存
* @Cacheable(value=”testcache”,unless=”#userName.length()>2”)
*/
String unless() default "";
/**
* 是否使用异步模式
*/
boolean sync() default false;
}
@Cacheable注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存。
10.4 @CachePut
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
/**
* 缓存的名称,必须至少指定一个,我们可以简单的认为是命名空间。我们一般用项目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 缓存的key
*/
String key() default "";
/**
* key生成器,可以实现 org.springframework.cache.interceptor.KeyGenerator接口,来规定想要保存的key的格式
* 设置自定义的key生成器实现类对应Bean的名字
*/
String keyGenerator() default "";
/**
* 缓存管理器,我们可以实现CacheManager接口来实现缓存管理器
* 指定自定义的缓存管理器对应的Bean名称
*/
String cacheManager() default "";
/**
* Cache解析器,用于根据实际情况来动态解析使用哪个Cache,实现CacheResolver接口
* 指定自定义的Cache解析器对应的Bean名称
*/
String cacheResolver() default "";
/**
* 缓存的条件
*/
String condition() default "";
/**
* 否定缓存。当条件结果为TRUE时,就不会缓存
* @Cacheable(value=”testcache”,unless=”#userName.length()>2”)
*/
String unless() default "";
}
@CachePut注解的作用主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用 。简单来说就是用户更新缓存数据。但需要注意的是该注解的value 和 key 必须与要更新的缓存相同,也就是与@Cacheable相同。
10.5 @CacheEvict
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {
/**
* 缓存的名称,必须至少指定一个,我们可以简单的认为是命名空间。我们一般用项目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 缓存的key
*/
String key() default "";
/**
* key生成器,可以实现 org.springframework.cache.interceptor.KeyGenerator接口,来规定想要保存的key的格式
* 设置自定义的key生成器实现类对应Bean的名字
*/
String keyGenerator() default "";
/**
* 缓存管理器,我们可以实现CacheManager接口来实现缓存管理器
* 指定自定义的缓存管理器对应的Bean名称
*/
String cacheManager() default "";
/**
* Cache解析器,用于根据实际情况来动态解析使用哪个Cache,实现CacheResolver接口
* 指定自定义的Cache解析器对应的Bean名称
*/
String cacheResolver() default "";
/**
* 缓存的条件
*/
String condition() default "";
/**
* 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
*/
boolean allEntries() default false;
/**
* 是否在方法执行前就清空,缺省为 false,
* 如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
*/
boolean beforeInvocation() default false;
}
@CacheEvict能够根据一定的条件对缓存进行清空。
10.6 @Caching
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
@Caching用于组合多个Cache注解的使用。相当于在一个方法上面添加多个注解。
关于Spring Boot缓存这部分的内容,咱们可以试着去整合redis或者ehcache来使用。
十一 Spring MVC相关注解
Spring MVC相关注解 | 解释 |
---|---|
@Controller | 声明该类为SpringMVC中的Controller,用来处理http请求 |
@RestController | 组合注解,@Controller + @ResponseBody.意味着,该Controller的所有方法都默认加上了@ResponseBody |
@RequestMapping | 把htt请求映射到方法上去 |
@PathVariable | 用于接收路径参数,比如@RequestMapping(“/hello/{name}”)申明的路径,将注解放在参数中前,即可获取该值,通常作为Restful的接口实现方法 |
@RequestParam | 将请求参数绑定至方法参数 |
@RequestBody | 用于读取Request请求的body部分数据 |
@ResponseBody | 将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区 |
@ModelAttribute | 主要作用是绑定request或是form参数到模型(Model) |
@InitBinder | 用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Model中 |
@ExceptionHandler | 用于全局处理控制器里的异常 |
@ControllerAdvice | 通过该注解,我们可以将对于控制器的全局配置放置在同一个位置,和@Controller对应 |
@RestControllerAdvice | 同上和@RestController对应 |
11.1 @Controller
@Target({ElementType.TYPE}) // 该注解用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* 用于显示指定组件的名称
* @Contorller 修饰的类对应的对象也是一个Bean,是一个注解,
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller的作用很简单,就是表示添加了该注解的类是负责处理由DispatcherServlet 分发的http请求的。
11.2 @RestController
@RestController是一个组合注解,@Controller+@ResponseBody。关于@ResponseBody的解释,我们会在下文讲到。
11.3 @RequestMapping
@Target({ElementType.METHOD, ElementType.TYPE}) // 可以作用于类,接口,方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
/**
* 为该映射起一个名字
*/
String name() default "";
/**
* 指定请求的实际地址
*/
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
/**
* 指定请求的method类型, GET、POST、PUT、DELETE等
*/
RequestMethod[] method() default {};
/**
* 指定request中必须包含某些参数值,才让该方法处理
* 1. param1: 表示请求必须包含名为param1的请求参数
* 2. !param1: 表示请求不能包含名为param1的请求参数
* 3. param1!=value1: 表示请求包含名为param1的请求参数,但其值不能为 value1
* 4. {"param1=value1", "param2"}: 请求必须包含名为 param1和param2的两个请求参数,且 param1参数的值必须为 value1
*/
String[] params() default {};
/**
* 指定request中必须包含某些指定的header值,才能让该方法处理请求。
* 比如, @RequestMapping(value = "/something", headers = "content-type=text/*")
* 将会匹配所有请求里面包含 Content-Type of "text/html", "text/plain", etc.
*/
String[] headers() default {};
/**
* 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html
* Examples:
* consumes = "text/plain"
* consumes = {"text/plain", "application/*"}
*/
String[] consumes() default {};
/**
* 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
* Examples:
* <pre class="code">
* produces = "text/plain"
* produces = {"text/plain", "application/*"}
* produces = MediaType.APPLICATION_JSON_UTF8_VALUE
* </pre>
*/
String[] produces() default {};
}
@RequestMapping是一个用来处理请求地址映射的注解。该注解可用于类或方法上,用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。@RequestMapping最终的目的就是把http对应的请求映射到对应的方法上。
11.3 @PathVariable
@Target(ElementType.PARAMETER) // 该注解用于添加在参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* 要绑定的路径变量的名称
*/
@AliasFor("value")
String name() default "";
/**
* 该属性是否是必须的,如果设置成必须的,但是路径里面没有传递该变量过来就抛出异常
*/
boolean required() default true;
}
@PathVariable注解用于从url中获取数据。
11.4 @RequestParam
@Target(ElementType.PARAMETER) // 该注解只能加载参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
/**
* 请求参数名
*/
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
/**
* 是否为必须参数
*/
boolean required() default true;
/**
* 默认值,没有匹配到参数情况下的默认值
*/
String defaultValue() default ValueConstants.DEFAULT_NONE;
}
@RequestParam用于将请求参数绑定至方法参数。
11.5 @RequestBody
@Target(ElementType.PARAMETER) // 该注解用于添加在参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
/**
* 该参数是否是必须的(是否非空)
*/
boolean required() default true;
}
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上。简单来说就是把Request请求对应的body数据映射成参数里面的对象。
11.6 @ResponseBody
@Target({ElementType.TYPE, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
11.7 @ModelAttribute
@Target({ElementType.PARAMETER, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* 要绑定的model属性的名称
*/
@AliasFor("value")
String name() default "";
/**
*
* 允许直接在ModelAttribute方法参数或从ModelAttribute方法返回的属性上声明数据绑定,这两种方法都会阻止该属性的数据绑定。
*/
boolean binding() default true;
}
@ModelAttribute注解的主要作用是绑定request或是form参数到模型(Model)对象。可以使用保存在request或session中的对象来组装模型对象。注意,被@ModelAttribute注解的方法会在controller方法(@RequestMapping注解的)之前执行。因为模型对象要先于controller方法之前创建。
11.7.1 @ModelAttribute添加在方法上
@ModelAttribute注解在方法上说明方法的作用是用于添加一个或多个属性到Model上。被@ModelAttribute注释的方法会在此Controller每个方法执行前被执行。因此对于一个Controller映射多个URL的用法来说,要谨慎使用。
11.7.1.1 @ModelAttribute添加在没有返回值的方法上
@ModelAttribute添加的方法没有返回值,一般这个时候我们需要自己去往Model里面添加数据了,要不然没啥意义。Model 就相当于每次请求的一个背包,我们可以往背包里面放东西。
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
*/
@ModelAttribute
public void postVoidModelAttribute(@RequestParam String abc, Model model) {
// 往model里面添加一个属性
model.addAttribute("userId0", abc);
}
11.7.1.2 @ModelAttribute添加在有返回值的方法上
@ModelAttribute添加在有返回值的方法上,会自动将该返回值放到Model里面去。
其实咱们这里的两个例子是等效的,都是把@RequestParam对应的值放到Model里面去了。
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
* @ModelAttribute 添加在有返回值的放的方法上,会把返回值放到Model里面去
*/
@ModelAttribute(value = "userId1")
public String postReturnModelAttribute(@RequestParam String abc) {
return abc;
}
11.7.2 @ModelAttribute添加在参数上
@ModelAttribute添加在参数上的时候用于从Model里面获取数据。上面我们已经通过把@ModelAttribute添加在方法上往Model里面添加了数据了,是时候取出来了。
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
* 会在其他添加了@RequestMapping的方法之前执行
*/
@ModelAttribute
public void postVoidModelAttribute(@RequestParam String abc, Model model) {
// 往model里面添加一个属性
model.addAttribute("userId0", abc);
}
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
* @ModelAttribute 添加在有返回值的放的方法上,会把返回值放到Model里面去
* 会在其他添加了@RequestMapping的方法之前执行
*/
@ModelAttribute(value = "userId1")
public String postReturnModelAttribute(@RequestParam String abc) {
return abc;
}
/**
* 上面我们已经通过把@ModelAttribute添加在方法上往Model里面去了,这个时候我们可以通过把@ModelAttribute添加在参数上获取Model里面的值
*/
@RequestMapping(value = "/text0")
public String test0(@RequestParam String abc, @ModelAttribute("userId0") String userId) {
System.out.println(userId);
return "helloWorld";
}
/**
* 其实我们也可以直接拿到Model
*/
@RequestMapping(value = "/text1")
public String helloWorld(@RequestParam String abc, Model model) {
Map<String, Object> mapList = model.asMap();
return "helloWorld";
}
11.8 @InitBinder
@Target({ElementType.METHOD}) // 该注解只能添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {
/**
* value,作用是限制对哪些 @RequestMapping 方法起作用,
* 具体筛选条件就是通过@RequestMapping方法入参来筛选,
* 默认不写就代表对所有@RequestMapping的方法起作用。
*/
String[] value() default {};
}
@InitBinder:用于给Binder做初始化,被@InitBinder注解的方法可以对WebDataBinder初始化。WebDataBinder是用于表单到方法的数据绑定的。只在添加了@InitBinder注解方法所在的控制器(Controller)里面有效。@InitBinder对应的方法在Controller的请求执行映射的方法之前被执行。同时添加了@InitBinder注解的方法返回值必须为null。
我们用一个具体的实例来说明@InitBinder的用法,可能有这么个场景,关于时间部分我们调用接口的时候传递的是 “2019-09-05” 的格式,但是我们后天需要Date的格式。这个时候@InitBinder就派上大用场了呀,我们可以通过@InitBinder配合WebDataBinder的使用帮我们把 “2019-09-05” 转换成Date。
@RestController
@RequestMapping(path = "/initBinder")
public class InitBinderController {
/**
* 对当前控制器的所有请求都有效
* 前台传递过来的String类型时间,通过下面的初始化绑定,转换成Date类型
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
// 我们前台传过来的time字段对应的值可能是“2019-05-06”这样的,我们可以在这里把他们转换成Date类型的
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
@RequestMapping(value = "/test", method = RequestMethod.POST)
public String helloWorld(@RequestBody InitBinderTestVo vo) {
System.out.println(vo.getTime());
return "success";
}
}
11.9 @ExceptionHandler
@Target(ElementType.METHOD) // 标记该注解是添加在方法上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* 当产生了哪些异常,就执行当前注解添加的方法
*/
Class<? extends Throwable>[] value() default {};
}
@ExceptionHandler用于全局处理控制器里的异常
11.10 @ControllerAdvice、@RestControllerAdvice
@Target(ElementType.TYPE) // 该注解是添加在类上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
/**
* 指定包下的控制器(Controller)
*/
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
/**
* 指定类所在的包和子包里面的控制器(Controller)
*/
Class<?>[] basePackageClasses() default {};
/**
* 直接给定控制器对应的class
*/
Class<?>[] assignableTypes() default {};
/**
* 添加了指定注解的控制器(Controller)
*/
Class<? extends Annotation>[] annotations() default {};
}
@ControllerAdvice(@RestControllerAdvice),Controller增强器。可以将对于控制器的全局配置(@ExceptionHandler、@InitBinder、@ModelAttribute)放在同一个位置(放到添加了@ControllerAdvice类中去实现)。所有有@ControllerAdvice出现的地方的类的方法里面肯定被@ExceptionHandler、@InitBinder、@ModelAttribute当中的一个修饰。
关于Spring Boot注解的简单介绍就这么写,希望能帮助到大家.