1.起因
- 记录IOC原理的时候就在想,这IOC读取xml文件然后进行反射创建对象,那注解的方式是怎么搞得呢?
于是就需要去了解注解到底是个什么。
2.注解
- 注解从类被加载到JVM虚拟机变成字节码流后,它其实是在字节码的属性表中的的RuntimeVisibleAnnotations中的,如果在类上注解就是在类的属性表中,如果在方法上注解,就在方法的属性表中。我个人觉得是不是可以理解为它其实也就是一个属性。书面定义它为元数据,即描述数据的数据。
- 注解的使用
J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:
@Documented –注解是否将包含在JavaDoc中
@Retention –什么时候使用该注解
@Target –注解用于什么地方
@Inherited – 是否允许子类继承该注解
@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
@Retention– 定义该注解的生命周期。
RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。
ElementType.TYPE:用于描述类、接口或enum声明
ElementType.FIELD:用于描述实例变量
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCTOR
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE 另一个注释
ElementType.PACKAGE 用于记录java文件的package信息
@Inherited – 定义该注释和子类的关系
那么,注解的内部到底是如何定义的呢?Annotations只支持基本类型、String及枚举类型。注释中所有的属性被定义成方法,并允许提供默认值。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interfaceTodo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default "Yash";
Priority priority()defaultPriority.LOW;
Status status() default Status.NOT_STARTED;
}
@Todo(priority = Todo.Priority.MEDIUM, author ="Yashwant", status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But it’s not complete yet
}
3.与IOC的关系
-
IOC其实就是在扫描注解,识别这些注解然后对不同注解进行不同的处理注入,Hibernate的校验就是对不同的注解进行不同的检查。AOP其实也是类似的原理。
-
IOC扫描到Autowire的注解后就会使用反射,对象的属性进行设置。至于扫描我觉得,应该是在所有的类加载如JVM中后,对字节码流中的属性表进行的扫描,动态的进行操作。
网友评论