一、注解的作用:
注解(Annotation)提供了一种安全的类似注释的机制,为我们在代码中添加信息提供了一种形式化得方法,使我们可以在稍后某个时刻方便的使用这些数据(通过解析注解来使用这些数据),用来将任何的信息或者元数据与程序元素(类、方法、成员变量等)进行关联。其实就是更加直观更加明了的说明,这些说明信息与程序业务逻辑没有关系,并且是供指定的工具或框架使用的。
1.生成文档。这是最常见的,也是java最早提供的注解。常用的有@see @param @return 等;
2.跟踪代码依赖性,替代配置文件。比较常见的是spring 2.5 开始的基于注解配置。作用就是减少配置。现在的框架基本都使用了这种配置来减少配置文件的数量;
3.在编译时进行格式检查。如@Override放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出。
二、注解的创建和使用:
java.lang.annotation包中包含了定义自定义注解时所要用到的原注解和接口。如接口Annotation是所有注解继承的接口,并且是自动继承,不需要定义时指定,类似于所有类都自动继承Object。包里同时定义了四个元注解,Documented,Inherited,Target,Retention。
@Target指注解用于什么地方,所有取值存放在枚举ElemenetType中,包括:
ElemenetType.CONSTRUCTOR---------------构造器声明
ElemenetType.FIELD -------------------------域声明(包括 enum 实例)
ElemenetType.LOCAL_VARIABLE-------------局部变量声明
ElemenetType.METHOD---------------------方法声明
ElemenetType.PACKAGE ---------------------包声明
ElemenetType.PARAMETER ------------------参数声明
ElemenetType.TYPE---------------------------类,接口(包括注解类型)或enum声明
@Retention指注释要保留多久。所有取值存放在枚举RetentionPolicy 中,包括:
RetentionPolicy.SOURCE---------------------------------注解将被编译器丢弃,保留注解到java源文件阶段
RetentionPolicy.CLASS -----------------------------------注解在class文件中可用,但会被VM丢弃,保留注解到class文件阶段
RetentionPolicy.RUNTIME-------保留注解到运行时阶段即内存中的字节码,将在运行期也保留注释,因此可以通过反射机制读取注解的信息。
@Documented 将注解包含在javadoc中,它代表着注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。相当与@see,@param 等。
@Inherited允许子类继承父类中的注解。
@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
public @interface TestA {
String name() default "johness"; //使用注解时需要一个String类型的参数,名为" name ",默认值为" johness"
}
使用实例:@TestA(name="aaa")
三、注解中参数的获取:
SayHiEmlement element = new SayHiEmlement();
Method[] methods = SayHiEmlement.class.getDeclaredMethods();
for (Method method : methods) {
SayHiAnnotationannotationTmp = null;
if((annotationTmp = method.getAnnotation(SayHiAnnotation.class))!=null)// 检测是否使用了我们的注解
method.invoke(element,annotationTmp.paramValue());// 如果使用了我们的注解,我们就把注解里的"paramValue"参数值作为方法参数来调用方法
else
method.invoke(element, "Rose");// 如果没有使用我们的注解,我们就需要使用普通的方式来调用方法了
}
四、spring中的注解:
在spring.xml中配置<context:component-scan/>,让spring扫描指定包中的类,把bean(service,dao,model等)装入spring容器中。
<context:component-scan/>配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor)。
注意:当在spring中使用注解代替配置文件时,所有的bean(包括Controller,Service,Dao等)都要加注解,不然spring不会把它加载进容器里,这样在注入的时候会找不到该bean(报BeanCreationException错误)。
(1)@Autowired
当 Spring 容器启动时,将扫描 Spring 容器中所有 Bean,当发现 Bean中有@Autowired注释的成员(成员变量,构造函数,setter方法)时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。
用在类成员上。
(2)@Service
告诉spring容器,这是一个Service类,默认情况会自动加载它到spring容器里。
用在类上。
(3)@Repository
将DAO类标识为SpringBean,只能标注在 DAO 类上。
用在类上。
(4)@ Resource
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,面@Resource默认按byName自动注入罢了。@Resource有两个属性是比较重要的,分别是nametype,Spring将@Resource注释的name 属性解析为Bean的名字,而type属性则解析为Bean的类型。所以如果使用name 属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
五、注解与XML配置:
通过使用@Component、@Repository、@Service和@Controller注解,同时启动Spring容器的类扫描机制(配置<context:component-scan/>)就可以从XML配置文件中完全移除Bean定义的配置。