资讯专栏INFORMATION COLUMN

关于微服务你不得不知道的事——Spring Boot注解分析

nevermind / 2953人阅读

摘要:注解分析注解定义注解,用于为代码提供元数据。我们可以将元注解看成一种特殊的修饰符,用来解释说明注解,它是注解的元数据。被修改的注解,结合可以指定该注解存在的声明周期。新增的可重复注解。

Spring Boot 注解分析

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 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 configurations = getCandidateConfigurations(annotationMetadata,
        attributes);
  configurations = removeDuplicates(configurations);
  Set exclusions = getExclusions(annotationMetadata, attributes);
  checkExcludedClasses(configurations, exclusions);
  configurations.removeAll(exclusions);
  configurations = filter(configurations, autoConfigurationMetadata);
  fireAutoConfigurationImportEvents(configurations, exclusions);
  return new AutoConfigurationEntry(configurations, exclusions);

}

protected List getCandidateConfigurations(AnnotationMetadata metadata,

     AnnotationAttributes attributes) {
  List 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 loadFactoryNames(Class factoryClass, @Nullable ClassLoader classLoader) {

  String factoryClassName = factoryClass.getName();
  return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());

}

点开loadSpringFactories

Enumeration 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.factoriesfile).

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 @Beanmethods. 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环境下创建

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/75374.html

相关文章

  • 关于Spring Boot得不知道的事

    摘要:采用一套固化的认知来建立生产环境准备的应用。我们采用一套关于固化平台和第三包依赖库的认知,以至于你可以通过最小的烦恼来启动。大多数的应用程序只需要非常少的配置。 1 Spring Boot官网[2.1.5 CURRENT GA] 1.1 Pivotal Wiki Pivotal Software, Inc. is a software and services company base...

    ygyooo 评论0 收藏0
  • 关于Spring Boot得不知道的事--Spring Boot的基本操作

    摘要:版本和编码方式依赖管理这样比如使用的时候就不需要指定版本号使用自己的项目这时候将依赖管理的问题放到中。 1 Pom文件1.1 spring-boot-starter-parent表示当前pom文件从spring-boot-starter-parent继承下来,在spring-boot-starter-parent中提供了很多默认配置,可以简化我们的开发。 org.springfram...

    fancyLuo 评论0 收藏0
  • Nacos系列:基于Nacos的配置中心

    摘要:杀只鸡而已,你拿牛刀来做甚释义小团队小项目选择简单的配置管理方式就好了,要什么配置中心,纯属没事找事。,我就啰嗦到这里吧,下面正式介绍作为配置中心是怎么使用的。 前言 在看正文之前,我想请你回顾一下自己待过的公司都是怎么管理配置的,我想应该会有以下几种方式: 1、硬编码没有什么配置不配置的,直接写在代码里面,比如使用常量类优势:对开发友好,开发清楚地知道代码需要用到什么配置劣势:涉及秘...

    ralap 评论0 收藏0
  • Spring Web

    摘要:认证鉴权与权限控制在微服务架构中的设计与实现一引言本文系认证鉴权与权限控制在微服务架构中的设计与实现系列的第一篇,本系列预计四篇文章讲解微服务下的认证鉴权与权限控制的实现。 java 开源项目收集 平时收藏的 java 项目和工具 某小公司RESTful、共用接口、前后端分离、接口约定的实践 随着互联网高速发展,公司对项目开发周期不断缩短,我们面对各种需求,使用原有对接方式,各端已经很...

    Kosmos 评论0 收藏0
  • Java 服务实践

    摘要:个人认为将此等思想放诸四海而皆准,在微服务的实践过程中,同样需要谨慎因应。不患无位,患所以立当微服务被广泛地被业界认可和接受时,或许你总会担心在何处实践,因此,在心态上 楔子 目前业界最流行的微服务架构正在或者已被各种规模的互联网公司广泛接受和认可,业已成为互联网开发人员必备技术。无论是互联网、云计算还是大数据,Java平台已成为全栈的生态体系,其重要性几乎不可替代。 这两年微服务作为...

    miguel.jiang 评论0 收藏0

发表评论

0条评论

nevermind

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<