编写不易,转载请注明(http://shihlei.iteye.com/blog/2406149)!
一 Java Annotation
(1)概述:
Annotation:主要用于对其他元素进行描述。包括Annotation,Class , Method, Field 等。
(2)Demo:
package x.demo.spring.core.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@interface Desc {
/**
* 描述
*
* @return 描述信息
*/
String value() default "";
}
//被注解的bean
@Desc("simple bean")
class Bean {
}
public class SimpleAnnotationDemo {
public static void main(String[] args) {
Desc desc = Bean.class.getAnnotation(Desc.class);
System.out.println("bean desc : " + desc.value());
}
}
(3)Meta Annotation 介绍:
(a)@Target:Annotation可应用于哪种Java 元素
其中ElementType说明:
-
- TYPE:Class ,Interface(包括Annotation),枚举
- FIELD:属性
- METHOD:方法
- PARAMETER:参数
- CONSTRUCTOR:构造函数
- LOCAL_VARIABLE:局部变量
- ANNOTATION_TYPE:Annotation
- PACKAGE:包
- TYPE_PARAMETER:类型参数,1.8新增
- TYPE_USE:类型使用:1.8新增
(b)@Retention:Annotation能保存到什么时候
其中RetentionPolicy说明:
- SOURCE:源文件有效
- CLASS:Class文件有效
- RUNTIME:运行时有效,可以通过反射读取
(c)@Inherited:类能否继承到父类的Annotation
二 Spring AnnotationUtils AnnocationElementUtils
(1)概述
Java 运行时读取Annotation 需要通过反射,Spring 提供AnnotationUtils , AnnotationElementUtils 用于简化操作,其他特点如下:
- 查询Meta Annotation(注解的注解)
- 对@AliasFor 解析,生成指定注解的代理,并赋值。(注:定义其他Annotation 的别名)
(2)Demo
(a) Dependency
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring</artifactId>
<groupId>x.demo.spring</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-core</artifactId>
<packaging>jar</packaging>
<name>spring-core</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</dependencies>
</project>
(b) Annotation
package x.demo.spring.core.anno.define;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
/**
* 单例的组件
* 这里组合了@Component , @Scope 所有spring 扫描时具有了这两个Annotation的能力:
*
* 单例,被扫描到并被容器实例化
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope("singleton")
@Component
@Inherited
public @interface SingletonComponent {
@AliasFor(annotation = Component.class, attribute = "value")
String value() default "";
}
(c) 使用Annotation
package x.demo.spring.core.anno.define;
/**
* 单例,被扫描到并被容器实例化
*/
@SingletonComponent("simpleService")
public class SimpleSingletonService {
}
(d)解析
package x.demo.spring.core.anno;
import java.util.Map;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Scope;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import x.demo.spring.core.anno.define.SimpleSingletonService;
import x.demo.spring.core.anno.define.SingletonComponent;
@ComponentScan
public class AnnotationUtilsDemo {
private static void annotationUtilsDemo() {
//获取类注解
SingletonComponent singletonComponentAnnocation = AnnotationUtils.findAnnotation(SimpleSingletonService.class, SingletonComponent
.class);
System.out.println("@SingletonComponent : " + singletonComponentAnnocation);
System.out.println("@SingletonComponent value: " + AnnotationUtils.getValue(singletonComponentAnnocation, "value"));
System.out.println("----------------------------------------------");
Scope scopeAnnocation = AnnotationUtils.findAnnotation(SimpleSingletonService.class, Scope.class);
System.out.println("@Scope : " + scopeAnnocation);
System.out.println("@Scope value: " + AnnotationUtils.getValue(scopeAnnocation, "scopeName"));
System.out.println("----------------------------------------------");
//获取@AliasFor Marge 后的注解,直接调用 AnnotationUtils的方法不会组合@AliasFor的值
Component componentAnnocation = AnnotatedElementUtils.findMergedAnnotation(SimpleSingletonService.class, Component.class);
System.out.println("@Component : " + componentAnnocation);
System.out.println("@Component value: " + AnnotationUtils.getValue(componentAnnocation, "value"));
}
//获取所有Annotation注解的类对象,获取Meta Annotation
private static void getAllAnnocations() {
try (AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();) {
context.register(AnnotationUtilsDemo.class);
context.refresh();
//@SingletonComponent 继承了 @Component 所以存在实例
Map<String, Object> beans = context.getBeansWithAnnotation(SingletonComponent.class);
for (Object bean : beans.values()) {
System.out.println("bean : " + bean);
Component componentAnnocation = AnnotatedElementUtils.findMergedAnnotation(bean.getClass(), Component.class);
System.out.println(componentAnnocation);
}
}
}
public static void main(String[] args) {
AnnotationUtilsDemo.annotationUtilsDemo();
System.out.println("----------------------------------------------");
AnnotationUtilsDemo.getAllAnnocations();
}
}
(e) 结果
@SingletonComponent : @x.demo.spring.core.anno.define.SingletonComponent(value=simpleService) @SingletonComponent value: simpleService ---------------------------------------------- @Scope : @org.springframework.context.annotation.Scope(value=singleton, scopeName=singleton, proxyMode=DEFAULT) @Scope value: singleton ---------------------------------------------- @Component : @org.springframework.stereotype.Component(value=simpleService) @Component value: simpleService ---------------------------------------------- bean : x.demo.spring.core.anno.define.SimpleSingletonService@74a10858 @org.springframework.stereotype.Component(value=simpleService)
(3)说明
(a)Utils 调用涉及的元素:
- Annotation: Annotation 元数据
- AnnotatedElement: 被Annotation注解的对象,包括annotation , class , method等
- Method: 类和接口中的方法信息
(b)常用方法:
- getAnnotation: 从某个类获取某个annotation
- findAnnotation: 从类或方法中查找某个annotation。
- isAnnotationDeclaredLocally: 验证annotation是否直接注释在类上而不是集成来的。
- isAnnotationInherited: 验证annotation是否继承于另一个class。
- getAnnotationAttributes: 获取annotation的所有属性。
- getValue: 获取指定annotation的值.
- getDefaultValue: 获取指定annotation或annotation 属性的默认值