Spring Boot注解分析

栏目: Java · 发布时间: 5年前

内容简介:Annotation(注解),用于为Java代码提供元数据。简单理解注解可以看做是一个个标签,用来标记代码。是一种应用于类、方法、参数、变量、构造器及包的一种特殊修饰符。元注解就是注解到注解上的注解,或者说元注解是一种基本注解,它能用来注解其他注解。我们可以将元注解看成一种特殊的修饰符,用来解释说明注解,它是注解的元数据。

1 注解

1.1 定义

Annotation(注解),用于为 Java 代码提供元数据。简单理解注解可以看做是一个个标签,用来标记代码。是一种应用于类、方法、参数、变量、构造器及包的一种特殊修饰符。

1.2 注解的声明

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation{

}

1.3 元注解

元注解就是注解到注解上的注解,或者说元注解是一种基本注解,它能用来注解其他注解。

我们可以将元注解看成一种特殊的修饰符,用来解释说明注解,它是注解的元数据。

  • @Documented

被@Documented修饰的Annotation类将会被javadoc工具提取成文档。

  • @Inherited

被@Inherited修改的Annotation将具有继承性,如果某个类使用了@MyAnnotation注解(定义该Annotation时使用了@Inherited修饰)修饰,则其子类将自动被@MyAnnotation修饰。

  • @Retention

被@Retention修改的注解,结合RetentionPolicy.XXX可以指定该注解存在的声明周期。

SOURCE:仅存在Java源码文件,经过编译器后便丢弃
CLASS:存在Java源文件,以及经过编译器后生成的Class字节码文件,但在运行时JVM中不再保留
RUNTIME:存在源文件、变异生成的Class字节码文件,以及保留在运行时JVM中,可以通过反射读取注解信息
  • @Target

表示该注解类型所使用的程序元素类型,结合ElementType.XXX来使用。

  • @Repeatable

Java8新增的可重复注解。

1.4 JDK中常见注解

  • @Override

用于告知编译器,我们需要覆写超类的当前方法。

  • @Deprecated

使用这个注解,用于告知编译器,某一程序元素(比如方法,成员变量)不建议使用了(即过时了)。

  • @SuppressWarnings

用于告知编译器忽略特定的警告信息,例在泛型中使用原生数据类型,编译器会发出警告,当使用该注解后,则不会发出警告。

  • @FunctionalInterface

用户告知编译器,检查这个接口,保证该接口是函数式接口,即只能包含一个抽象方法,否则就会编译出错。

1.5 自定义注解使用

  • 格式

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotataion{
String name();
    int age() default 17;
    String hello() default "spring boot";
}
  • 成员变量

定义:用无形参的方法形式来声明,注解方法不能带参数,比如name(),age()

类型:前面可以用数据类型来修饰

默认值:成员变量可以有默认值,比如default "spring boot"

  • 注解使用

@MyAnnotation(name="Jack",age=16)
public class Person {
}
  • 反射获取类上的注解

//1.获取需要解析注解的类
Class<Person> clazz=Person.class;
//2.判断该类上是否有注解
if(clazz.isAnnotationPresent(MyAnnotation.class)){
    //3.获取该类上的注解
    MyAnnotation myAnnotation=clazz.getAnnotation(MyAnnotation.class);
    //4.打印出注解上的内容
    System.out.println(myAnnotation.name()+":"+myAnnotation.age());
}

2 @SpringBootApplication

官网见:18. Using the @SpringBootApplication Annotation

The @SpringBootApplication annotation is equivalent to using @Configuration , @EnableAutoConfiguration , and @ComponentScan with their default attributes

@SpringBootConfiguration等同于@Configuration

3 @SpringBootConfiguration

@SpringBootConfiguration等同于@Configuration,@Configuration等同于@Component

3.1 作用

@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类。

并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到Spring容器中,实例名就是方法名。

3.2 使用

  • @Configuration : allow to register extra beans in the context or import additional configuration classes

@SpringBootConfiguration
public class Config{
    @Bean
    public Map getMap(){
        Map map=new HashMap();
        map.put("username","Jack");
        return map;
    }
}

可以直接通过context.getBean("getMap")的方式获取。

3.3 扩展

@Configuration等同与@Component

官网见[Spring Framework Core]:1.10.1. @Component and Further Stereotype Annotations

conclusion :@Component includes @Configuration,@Repository,@Service and @Controller

4 @ComponentScan

  • @ComponentScan : enable @Component scan on the package where the application is located (see the best practices )

官网见[Spring Framework Core]:1.10.3. Automatically Detecting Classes and Registering Bean Definitions

To autodetect these classes and register the corresponding beans, you need to add @ComponentScan to your @Configuration class, where the basePackages attribute is a common parent package for the two classes. (Alternatively, you can specify a comma- or semicolon- or space-separated list that includes the parent package of each class.)

@ComponentScan主要就是定义扫描的路径以及子路径中,找出标识了需要装配的类自动装配到Spring的bean容器中。

官网见:17. Spring Beans and Dependency Injection

If you structure your code as suggested above (locating your application class in a root package), you can add @ComponentScan without any arguments. All of your application components ( @Component , @Service , @Repository , @Controller etc.) are automatically registered as Spring Beans.

5 @EnableAutoConfiguration

  • @EnableAutoConfiguration : enable Spring Boot’s auto-configuration mechanism

官网见:11.3.2 The @EnableAutoConfiguration Annotation

The second class-level annotation is @EnableAutoConfiguration . This annotation tells Spring Boot to “guess” how you want to configure Spring, based on the jar dependencies that you have added. Since spring-boot-starter-web added Tomcat and Spring MVC, the auto-configuration assumes that you are developing a web application and sets up Spring accordingly.

5.1 @Import(XXX)

借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助Spring Boot应用将所有符合条件的@Configuration配置都加载到IoC容器中

5.2 SpringFactoriesLoader

  • selectImports方法

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return NO_IMPORTS;
   }
   AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
         .loadMetadata(this.beanClassLoader);
   AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
         autoConfigurationMetadata, annotationMetadata);
   return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
  • 读取候选装配组件getCandidateConfigurations

protected AutoConfigurationEntry getAutoConfigurationEntry(
      AutoConfigurationMetadata autoConfigurationMetadata,
      AnnotationMetadata annotationMetadata) {
   if (!isEnabled(annotationMetadata)) {
      return EMPTY_ENTRY;
   }
   AnnotationAttributes attributes = getAttributes(annotationMetadata);
   List<String> configurations = getCandidateConfigurations(annotationMetadata,
         attributes);
   configurations = removeDuplicates(configurations);
   Set<String> exclusions = getExclusions(annotationMetadata, attributes);
   checkExcludedClasses(configurations, exclusions);
   configurations.removeAll(exclusions);
   configurations = filter(configurations, autoConfigurationMetadata);
   fireAutoConfigurationImportEvents(configurations, exclusions);
   return new AutoConfigurationEntry(configurations, exclusions);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
      AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
         getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
   Assert.notEmpty(configurations,
         "No auto configuration classes found in META-INF/spring.factories. If you "
               + "are using a custom packaging, make sure that file is correct.");
   return configurations;
}
  • SpringFacotriesLoader.loadFactoryNames

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
   String factoryClassName = factoryClass.getName();
   return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}

点开loadSpringFactories

Enumeration<URL> urls = (classLoader != null ?
      classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
      ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

点开FACTORIES_RESOURCE_LOCATION

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

5.3 autoconfigure.jar

# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

6 @Conditional

* Indicates that a component is only eligible for registration when all
* {@linkplain #value specified conditions} match.

6.1 Understanding Auto-Configured Beans

官网见:49.1 Understanding Auto-configured Beans

Under the hood, auto-configuration is implemented with standard @Configuration classes. Additional @Conditional annotations are used to constrain when the auto-configuration should apply. Usually, auto-configuration classes use @ConditionalOnClass and @ConditionalOnMissingBean annotations. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own @Configuration .

You can browse the source code of spring-boot-autoconfigure to see the @Configuration classes that Spring provides (see the META-INF/spring.factories file).

6.2 Condition Annotations

官网见:49.3 Condition Annotations

You almost always want to include one or more @Conditional annotations on your auto-configuration class. The @ConditionalOnMissingBean annotation is one common example that is used to allow developers to override auto-configuration if they are not happy with your defaults.

Spring Boot includes a number of @Conditional annotations that you can reuse in your own code by annotating @Configuration classes or individual @Bean methods. These annotations include:

  • Section 49.3.1, “Class Conditions”

  • Section 49.3.2, “Bean Conditions”

  • Section 49.3.3, “Property Conditions”

  • Section 49.3.4, “Resource Conditions”

  • Section 49.3.5, “Web Application Conditions”

  • Section 49.3.6, “SpEL Expression Conditions”

翻译 :不同类型的Conditional

(1)ConditionalOnClass:当且仅当ClassPath存在指定的Class时,才创建标记上该注解的类的实例

(2)ConditionalOnBean: 当且仅当指定的bean classes and/or bean names在当前容器中,才创建标记上该注解的类的实例

(3)ConditionalOnProperty:当且仅当Application.properties存在指定的配置项时,创建标记上了该注解的类的实例

(4)ConditionalOnResource:在classpath下存在指定的resource时创建

(5)ConditionalOnWebApplication:在web环境下创建

大家扫描下方二维码关注下我的微信公众号

公众号没有福利,只会定期生产技术性文章!

Spring Boot注解分析


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据分析技术白皮书

数据分析技术白皮书

伍海凤、刘鹏、杨佳静、马师慧Sara、李博、Shirley Song、Zinc、李晓艳 / 2016-8-11 / 0

关于数据分析技术白皮书(Analytics Book 中文版),主要内容围绕: 1. 分析(Analytics):网站分析 & APP分析 2. 谷歌分析工具的原理、部署与使用 3. 开源网站分析工具的原理、部署与使用 4. Log日志分析原理 5. 网站分析的维度与指标定义 6. 如何炼成为一个互联网数据分析师 请访问书的数据分析技术白皮书官网“免费”阅......一起来看看 《数据分析技术白皮书》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具