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 自定义注解使用

  • 格式

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

}
  • 成员变量

定义:用无形参的方法形式来声明,注解方法不能带参数,比如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

官网见: 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.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:

翻译:不同类型的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的注解,你知道或者不知道的都在这里!的更多相关文章

  1. Spring Boot常用注解总结

    Spring Boot常用注解总结 @RestController和@RequestMapping注解 @RestController注解,它继承自@Controller注解.4.0之前的版本,Spr ...

  2. Spring Boot 常用注解汇总

    一.启动注解 @SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documen ...

  3. 3个Spring Boot核心注解,你知道几个?

    Spring Boot 核心注解讲解 Spring Boot 最大的特点是无需 XML 配置文件,能自动扫描包路径装载并注入对象,并能做到根据 classpath 下的 jar 包自动配置. 所以 S ...

  4. Spring Boot@Component注解下的类无法@Autowired的问题

    title: Spring Boot@Component注解下的类无法@Autowired的问题 date: 2019-06-26 08:30:03 categories: Spring Boot t ...

  5. Spring boot 基于注解方式配置datasource

    Spring boot 基于注解方式配置datasource 编辑 ​ Xml配置 我们先来回顾下,使用xml配置数据源. 步骤: 先加载数据库相关配置文件; 配置数据源; 配置sqlSessionF ...

  6. 【SpringBoot】15. Spring Boot核心注解

    Spring Boot核心注解 1 @SpringBootApplication 代表是Spring Boot启动的类 2 @SpringBootConfiguration 通过bean对象来获取配置 ...

  7. spring boot纯注解开发模板

    简介 spring boot纯注解开发模板 创建项目 pom.xml导入所需依赖 点击查看源码 <dependencies> <dependency> <groupId& ...

  8. Spring Boot中注解@ConfigurationProperties

    在Spring Boot中注解@ConfigurationProperties有三种使用场景,而通常情况下我们使用的最多的只是其中的一种场景.本篇文章带大家了解一下三种场景的使用情况. 场景一 使用@ ...

  9. 关于RecyclerView你知道的不知道的都在这了(下)

    目录 目录 正文 6. Recycler 7. ItemAnimator 8. ItemDecoration 9. OnFlingListener 目录 由于本篇篇幅特长,特意做了个目录,让大伙对本篇 ...

随机推荐

  1. PAT 1013 Battle Over Cities DFS深搜

    It is vitally important to have all the cities connected by highways in a war. If a city is occupied ...

  2. node-express脚手架生成的项目中实现浏览器缓存

    前言: 最近在做基于 node-express 的个人站点 朵朵视野 ,在站点发布之后自己在访问测试的过程中发现站点是没有缓存机制的,这样就导致每次访问站点都需要重新去加载资源,很消耗资源以及用户体验 ...

  3. AQS(AbstractQueuedSynchronizer)解析

    AbstractQueuedSynchronizer是JUC包下的一个重要的类,JUC下的关于锁相关的类(如:ReentrantLock)等大部分是以此为基础实现的.那么我们就来分析一下AQS的原理. ...

  4. Angular ElementRef详解

    一.为什么要用ElementRef Angular 的口号是 - "一套框架,多种平台.同时适用手机与桌面 (One framework.Mobile & desktop.)&quo ...

  5. 如何去除小程序button的边框

    小程序button 自带样式,就算用 border:none: background:none ,还是会有一条细的边框 使用:after选择器就可以去除 button::after{ border:n ...

  6. 程序运行时间测试 - 使用系统函数 getrusage 获取程序运行时间

    https://github.com/yaowenxu/Workplace/blob/master/timer/getrusagetimer.c 关键结构体: struct rusage { stru ...

  7. 一个EMFILE问题定位:lsof、ulimit的应用,以及简单分析

    关键词:errno.EMFILE.ulimit.lsof等等. 背景是在对程序进行压力测试,运行了一段时间之后出现一个复位操作失败. 这个复位操作通过打开一个设备,进行读写操作,已达到控制GPIO输入 ...

  8. linux 头文件路径

    linux 头文件路径 /usr/include

  9. A1071 Speech Patterns (25 分)

    一.技术总结 开始拿到这道题目时,思考的是我该如何区分它们每一个单词,不知道这里还是要学习得知在cctype头文件中有一个函数用于查看是否为0~9.a~z.A~Z,就是isalnum(),又因为题目中 ...

  10. Codeforces Round #603 (Div. 2) F. Economic Difficulties dp

    F. Economic Difficulties An electrical grid in Berland palaces consists of 2 grids: main and reserve ...