Spring Boot 注解收集

       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注解的简单介绍就这么写,希望能帮助到大家.

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容