java SE 中的注解:
一、注解分类:
1.由编译器使用的注解
例如:
@Override:让编译器检查该方法是否正确地实现了覆写;
@SuppressWarnings:告诉编译器忽略此处代码产生的警告。
@Deprecated:该注解标注的内容,表示已过时
这类注解不会被编译进入.class文件,它们在编译后就被编译器扔掉了。
2.由工具处理.class文件使用的注解
比如有些工具会在加载class的时候,对class做动态修改,实现一些特殊的功能。
这类注解会被编译进入.class文件,但加载结束后并不会存在于内存中。这类注解只被一些底层库使用,一般我们不必自己处理。
3.在程序运行期能够读取的注解,它们在加载后一直存在于JVM中,这也是最常用的注解。
例如,一个配置了@PostConstruct的方法会在调用构造方法后自动被调用(这是Java代码读取该注解实现的功能,JVM并不会识别该注解)
二、自定义注解:
格式:
元注解
public @interface 注解名称{
属性列表;
}
三、元注解:
有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)
@Target:描述注解能够作用的位置
ElementType.TYPE:可以作用于类上
ElementType.METHOD:可以作用于方法上
ElementType.FIELD:可以作用于成员变量上
ElementType.CONSTRUCTOR:可以作用在构造方法上
ElementType.PARAMETER:可以作用在方法的参数上
@Retention:定义了Annotation的生命周期
RetentionPolicy.SOURCE:仅编译期
RetentionPolicy.CLASS:仅class文件
RetentionPolicy.RUNTIME:运行期
SOURCE类型的注解主要由编译器使用,因此我们一般只使用,不编写。
CLASS类型的注解主要由底层工具库使用,涉及到class的加载,一般我们很少用到。
只有RUNTIME类型的注解不但要使用,还经常需要编写。
@Inherited:定义子类是否可继承父类定义的Annotation。
@Inherited仅针对@Target(ElementType.TYPE)类型的annotation有效,并且仅针对class的继承,对interface的继承无效。
@Documented:描述注解是否被抽取到api文档中
@Repeatable:描述这个元注解修饰的Annotation是否可重复。
SpringBoot中注解的分析:
这是每一个springboot项目的启动类,通过这个@SpringBootApplication这个注解就将整个项目启动起来了,咱们来看看这个注解到底是怎么做到的:
不难发现跟我们上边说的声明一个注解的方式一样,咱们把元注解删掉再看
就只剩下@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan,也可以说@SpringBootApplication就是这个三个注解
1.@SpringBootConfiguration:
看图这个注解是由@Document和@Configuration组成的。
从图中不难看出@Document是一个空的注解不用关心,而我们关系的则是@Configuration,而在图中我们可以看到了我们熟悉的@Component这个注解,在Spring框架中看见过是用来把普通pojo实例化到spring容器中,相当于配置文件中的
图中可以看出是由@AutoConfigurationPackage和@Import组成
从图中可以看@AutoConfigurationPackage这个注解也被@Import所用到,咱们单独看这个@Import,字面意思是导入的意思,导入什么那,看传入的值AutoConfigurationImportSelector.class,这个类是做什么的
经过代码的分析我们发现一个spring.factories的文件这里边是我们启动代码时所用的类的全路径都放到了这个文件中。
3.@ComponentScan作用:扫描并注册带@Component以及扩展的标注(如@Controller、@Service、@Respository等)的类