`
阅读更多
编写不易,转载请注明(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说明:

 

    1.     TYPE:Class ,Interface(包括Annotation),枚举
    2.     FIELD:属性
    3.     METHOD:方法
    4.     PARAMETER:参数
    5.     CONSTRUCTOR:构造函数
    6.     LOCAL_VARIABLE:局部变量
    7.     ANNOTATION_TYPE:Annotation
    8.     PACKAGE:包
    9.     TYPE_PARAMETER:类型参数,1.8新增
    10.     TYPE_USE:类型使用:1.8新增 

(b)@Retention:Annotation能保存到什么时候

其中RetentionPolicy说明:

 

  1.     SOURCE:源文件有效
  2.     CLASS:Class文件有效
  3.     RUNTIME:运行时有效,可以通过反射读取

(c)@Inherited:类能否继承到父类的Annotation

 

二 Spring AnnotationUtils AnnocationElementUtils

(1)概述

Java 运行时读取Annotation 需要通过反射,Spring 提供AnnotationUtils , AnnotationElementUtils 用于简化操作,其他特点如下:

 

  1. 查询Meta Annotation(注解的注解)
  2. 对@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 调用涉及的元素:

  1. Annotation: Annotation 元数据
  2. AnnotatedElement: 被Annotation注解的对象,包括annotation , class , method等
  3. Method: 类和接口中的方法信息

 

(b)常用方法:

  1. getAnnotation: 从某个类获取某个annotation
  2. findAnnotation: 从类或方法中查找某个annotation。
  3. isAnnotationDeclaredLocally: 验证annotation是否直接注释在类上而不是集成来的。
  4. isAnnotationInherited: 验证annotation是否继承于另一个class。
  5. getAnnotationAttributes: 获取annotation的所有属性。
  6. getValue: 获取指定annotation的值. 
  7. getDefaultValue: 获取指定annotation或annotation 属性的默认值

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics