注解产生的原因
在注释之前(甚至之后),XML被广泛用于框架的配置,开发人员和架构师认为XML维护变得越来越麻烦。 他们想要某些东西可以与代码紧密耦合而不是XML,而XML与代码之间的耦合非常松散(在某些情况下,几乎是分开的)。
如果搜索“ XML与注释”,会发现很多有趣的争论。 有趣的一点是,引入了XML配置可以将配置与代码分开。 注解可以提供更大的便捷性,易于维护修改,但耦合度高,而 XML 相对于注解则是相反的。
如今,大多数框架都将XML和注解结合使用,以充分利用两者的积极方面。
xml 和 注解的使用场景与区别
注解:是一种分散式的元数据,与源代码紧绑定。
xml:是一种集中式的元数据,与源代码无绑定。
- 通用配置XML,比如事务配置,比如数据库连接池等等,即通用的配置集中化,而不是分散化,如很多人使用
- 假设您要设置一些应用程序范围内的常量/参数。 在这种情况下,XML是一个更好的选择,因为它与任何特定的代码段都不相关。
- 注解相对于XML的另一个好处是类型安全的,XML只能在运行期才能发现问题。
什么是注解
-
不是程序本身,只是对程序做出某种解释,
-
但是可以被其他的程序读取。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
这是注解 @Override 的定义,其实它本质上就是:
public interface Override extends Annotation{
}
注解的本质就是一个继承了 Annotation 接口的接口。有关这一点,你可以去反编译任意一个注解类,你会得到结果的。
解析一个类或者方法的注解往往有两种形式,一种是编译期直接的扫描,一种是运行期反射。反射的事情我们待会说,而编译器的扫描指的是编译器在对 java 代码编译字节码的过程中会检测到某个类或者方法被一些注解修饰,这时它就会对于这些注解进行某些处理。
注解的本质,以及如何编写自定义注解
元注解
怎么理解:其实就是理解为描述注解的注解,元数据就是描述数据的数据,元类就是描述类的类。。。
@Target
@Retention
@Documented
@Inherited
@Target
作用:
- 用于描述注解的使用范围,被描述的注解可以用在什么地方。
- 也就是说用来修饰方法的或者是修饰字段属性的。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
//表示的是一个参数和参数的类型
}
@Retention
作用:
- 表示需要在什么级别保存该注解信息,用于描述注解的生命周期。
@Retention(value = RetentionPolicy.RUNTIME
自定义注解
package testAnnotations;/*
* This code demonstrates how to define an annotation.
*
* @author Yashwant Golecha (ygolecha@gmail.com)
* @version 1.0
*
*/
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Todo {
public enum Priority {LOW, MEDIUM, HIGH}
public enum Status {STARTED, NOT_STARTED}
String author() default "Yash";
Priority priority() default Priority.LOW;
Status status() default Status.NOT_STARTED;
}
package testAnnotations;
public class BusinessLogic {
public BusinessLogic() {
super();
}
public void compltedMethod() {
System.out.println("This method is complete");
}
@Todo(priority = Todo.Priority.HIGH)
public void notYetStartedMethod() {
// No Code Written yet
}
@Todo(priority = Todo.Priority.MEDIUM, author = "Uday", status = Todo.Status.STARTED)
public void incompleteMethod1() {
//Some business logic is written
//But its not complete yet
}
@Todo(priority = Todo.Priority.LOW, status = Todo.Status.STARTED )
public void incompleteMethod2() {
//Some business logic is written
//But its not complete yet
}
}
package testAnnotations;
import java.lang.reflect.Method;
public class TodoReport {
public TodoReport() {
super();
}
public static void main(String[] args) {
getTodoReportForBusinessLogic();
}
/**
* This method iterates through all messages of BusinessLogic class and fetches annotations defined on each of them.
* After that it displays the information from annotation accordingly.
*/
private static void getTodoReportForBusinessLogic() {
Class businessLogicClass = BusinessLogic.class;
for(Method method : businessLogicClass.getMethods()) {
Todo todoAnnotation = (Todo)method.getAnnotation(Todo.class);
if(todoAnnotation != null) {
System.out.println(" Method Name : " + method.getName());
System.out.println(" Author : " + todoAnnotation.author());
System.out.println(" Priority : " + todoAnnotation.priority());
System.out.println(" Status : " + todoAnnotation.status());
System.out.println(" --------------------------- ");
}
}
}
}