赞
踩
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一起出现 |
@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我们会在下面讲到。
@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显示的去指定要扫描的包名了。
因为@EnableAutoConfiguration、@SpringBootConfiguration、@Configuration这三是一体的,所以咱们把他们归到一起来说明。
@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注解。
@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的名称就是方法名。
@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容器里面去,供我们在别的地方使用。
@Target(ElementType.TYPE) // 指明该注解是添加在类上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* 需要import的类
*/
Class<?>[] value();
}
@Import注解用于帮助把我们需要的类导入到组件类里面去,有时没有把某个类注入到Spring IOC容器中,但在某个类使用的时候需要获取该类对应的Bean,此时就需要用到@Import注解。
@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(组件)。这样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注解就知道是业务层的代码。
Bean属性相关注解 | 解释 |
---|---|
@Scope | 设置Spring容器如何新建Bean实例,一般配合@Bean、@Component、@Service、@Repository一起使用 |
@PostConstruct | 在构造函数执行完之后执行 |
@PreDestory | 在Bean销毁之前执行 |
@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();
}
}
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@PostConstruct用来修饰一个分静态并且返回void的方法。该方法只会在构造函数之后执行一次。@PostConstruct一般@Component、@Service、@Repository修饰的对象里面使用。
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@PreDestroy也是用来修饰一个分静态并且返回void的方法。该方法只会在对象函数之后执行一次。@PreDestory和一样@PostConstruct一般也是在@Component、@Service、@Repository修饰的对象里面使用。
注入注解就是帮助我们自动引入依赖的对象。
Bean注入相关注解 | 解释 |
---|---|
@Autowired | 先按类型注入,然后按照名称注入,都无法找到唯一的一个实现类则报错 |
@Inject | 在Spring的环境下,@Inject和@Autowired是相同的 |
@Resource | 先按名字注入,再按类型注入,都无法找到唯一的一个出现异常 |
@Qualifier | 用于指定Bean的名字,一般配合用来配合@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的用法)
在Spring的环境下,@Inject和@Autowired是相同的。
@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名字去容器里面查找,如果没找到在通过类型去容器里面查找。
@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;
}
@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容器启动的加载时间。
@DependsOn
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
/**
* 依赖的Bean对应的名称
*/
String[] value() default {};
}
@DependsOn:控制Bean加载顺序。指定先加载@DependsOn对应的Bean。
读取配置文件相关的注解,就是用来帮助我们获取到配置文件*.properties、*.yam里面信息的。
读取配置文件相关注解 | 解释 |
---|---|
@EnableConfigurationProperties | 让使用@ConfigurationProperties注解的类生效 |
@ConfigurationProperties | 读取配置文件的信息,并自动封装成实体类 |
@PropertySource | 指定的属性文件(只能加载*.properties文件,不能加载yaml文件)映射到对象 |
@ImportResource | 导入Spring的*.xml配置文件,让xml配置文件里面的内容生效 |
@Target(ElementType.TYPE) // 添加在类上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties {
/**
* 对应于添加了@ConfigurationProperties的类,让他们生效
*/
Class<?>[] value() default {};
}
@EnableConfigurationProperties注解的作用是让使用@ConfigurationProperties注解的类生效。你可以通过在@EnableConfigurationProperties注解中直接简单的列出属性类来快捷的注册@ConfigurationProperties bean的定义。而且@EnableConfigurationProperties我们一般添加在Applicaiton类上面。
@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容器里面去了。
@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; } }
@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来配置的)。
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
*
* 实际值表达式
* 例如,{@code #{systemProperties.myProp}}.
*/
String value();
}
@Value注解用于将外部的值动态注入到Bean中,大概有如下这么几种情况:
/**
* 注入普通字符串,相当于private String normal = "normal"
*/
@Value("normal")
private String normal;
/**
* 注入操作系统属性
*/
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
/**
* 注入表达式结果,相当于 double randomNumber = java.lang.Math).random() * 100.0
*/
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
/**
* 注入其他Bean属性:相当于把IOC容器里面valueInject名字对应的对象的name属性赋值给变量
*/
@Value("#{valueInject.name}")
private String fromAnotherBean;
/**
* 注入文件资源,相当于把resource目录下valueInjectConfig.txt文件注入进来
*/
@Value("classpath:valueInjectConfig.txt")
private Resource valueInjectConfig;
/**
* 注入URL资源,相当于把http://www.baidu.com对应的资源注入进来
*/
@Value("http://www.baidu.com")
private Resource baiduUrl;
比如如下的例子我们加载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容器里面去 |
@Target({ElementType.TYPE, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
/**
* profile对应的名字。比如生成环境有一个名字,测试环境有一个名字
*/
String[] value();
}
@Profiles可以实现不同环境(开发、测试、部署等)使用不同的配置。任何@Component或@Configuration都能被@Profile标记,从而限制加载它的时机。
@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相关注解 | 解释 |
---|---|
@Aspect | 声明一个切面,只是一个标识作用 |
@PointCut | 声明切点,在java配置类中使用@EnableAspectJAutoProxy注解开启Spring对AspectJ代理的支持 |
@Around | 在方法执行之前与之后执行 |
@Before | 在方法执行之前执行 |
@After | 在方法执行之后执行 |
@AfterReturning | 方法正常退出的时候执行 |
@AfterThrowing | 方法有异常抛出的时候执行 |
@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注解只是一个标识作用。
@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中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 注解用于添加在方法上
public @interface Around {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@Around环绕增强,方法执行前和执行后都会执行。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@Before方法执行前执行。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {
/**
* 切入点表达式,一般配合@Pointcut一起使用
*/
String value();
/**
* 用来接收AspectJ表达式中的参数
*/
String argNames() default "";
}
@After方法执行后执行。
@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方法正常退出的时候执行。
@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
@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 | 异步方法 |
@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。
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
/**
*
* 指定异步操作的限定符值。
*/
String value() default "";
}
@Async可以把某一个方法或者类下面的方法全部变成异步处理的方法。
定时任务相关注解 | 解释 |
---|---|
@EnableScheduling | 在配置类上使用,开启计划任务的支持 |
@Scheduled | 来申明这是一个任务,包括cron,fixDelay,fixRate等类型 |
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
@EnableScheduling注解用于开启定时任务的支持。简单来说就是如果我们想在应用里面使用@Scheduled就需要添加@EnableScheduling注解。一般添加在主配置类上。
@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 | 控制事务注解 |
@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用于开启事务的支持,我们一般在主配置类上添加该注解。
@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注解的使用 |
@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的使用。
@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等这些注解上就可以不用重复去填这些参数了。
@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注解会先查询是否已经有缓存,有会使用缓存,没有则会执行方法并缓存。
@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相同。
@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能够根据一定的条件对缓存进行清空。
@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相关注解 | 解释 |
---|---|
@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对应 |
@Target({ElementType.TYPE}) // 该注解用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* 用于显示指定组件的名称
* @Contorller 修饰的类对应的对象也是一个Bean,是一个注解,
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Controller的作用很简单,就是表示添加了该注解的类是负责处理由DispatcherServlet 分发的http请求的。
@RestController是一个组合注解,@Controller+@ResponseBody。关于@ResponseBody的解释,我们会在下文讲到。
@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对应的请求映射到对应的方法上。
@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中获取数据。
@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用于将请求参数绑定至方法参数。
@Target(ElementType.PARAMETER) // 该注解用于添加在参数上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
/**
* 该参数是否是必须的(是否非空)
*/
boolean required() default true;
}
该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上。简单来说就是把Request请求对应的body数据映射成参数里面的对象。
@Target({ElementType.TYPE, ElementType.METHOD}) // 该注解用于添加在类或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。
@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方法之前创建。
@ModelAttribute注解在方法上说明方法的作用是用于添加一个或多个属性到Model上。被@ModelAttribute注释的方法会在此Controller每个方法执行前被执行。因此对于一个Controller映射多个URL的用法来说,要谨慎使用。
@ModelAttribute添加的方法没有返回值,一般这个时候我们需要自己去往Model里面添加数据了,要不然没啥意义。Model 就相当于每次请求的一个背包,我们可以往背包里面放东西。
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
*/
@ModelAttribute
public void postVoidModelAttribute(@RequestParam String abc, Model model) {
// 往model里面添加一个属性
model.addAttribute("userId0", abc);
}
@ModelAttribute添加在有返回值的方法上,会自动将该返回值放到Model里面去。
其实咱们这里的两个例子是等效的,都是把@RequestParam对应的值放到Model里面去了。
/**
* Model: 就相当于每次请求的一个背包,我们可以往背包里面放东西
* @ModelAttribute 添加在有返回值的放的方法上,会把返回值放到Model里面去
*/
@ModelAttribute(value = "userId1")
public String postReturnModelAttribute(@RequestParam String abc) {
return abc;
}
@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"; }
@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"; } }
@Target(ElementType.METHOD) // 标记该注解是添加在方法上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* 当产生了哪些异常,就执行当前注解添加的方法
*/
Class<? extends Throwable>[] value() default {};
}
@ExceptionHandler用于全局处理控制器里的异常
@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注解的简单介绍就这么写,希望能帮助到大家.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。