在java中实现组合注解原理分析(注解继承)

今天在自定义注解的时候,原计划实现一个类似于Spring中的注解@Component的功能,如果稍有留意一下,会发现,在Spring中我们常见的注解,其实都继承了@Component注解;如下图所示:

如上图所示,我们可以看到,我们常见的注解都继承了注解@Component,而spring在启动时进行类扫描的时候,也是扫描候选类上是否有携带@Component注解,有携带的话标记为候选资源,否则的话不进行扫描;

 

但是,我们的原生java是不支持直接获取当前类的所实现的注解的注解的;也就是说,我使用注解A标记了注解B,然后将注解B添加到类或者是方法上后,通过反射获取到当前类,无法直接获取到当前类是否有被注解A所标记;

 

那么,在spring中是如何实现这种注解的集成@Component的呢;在这里,使用代码简单实现一下注解的继承;

 

首先,先创建一个Maven工程,然后我们自定义一个注解@Component

/**
 * 基础注解,被此注解标记的类在spring扫描的包路径下的话会被加入候选资源中
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyComponent {

    String name() default "";
}

创建好基础注解后,我们再来创建一个注解@MyService,让这个注解继承基础注解@Component,代码如下:

/**
 * 类 名: MyService
 * 描 述: 自定义注解 -- 服务层 -- 定义在类、接口、枚举上的
 * @author: jiaYao
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@MyComponent
public @interface MyService {

}

 

准备好这些工作后,再来创建一个测试类,让这个测试类被注解@MySerice标记;

@MyService
public class UserService {
}

 

现在我们再写一个main方法即可开始测试,代码如下:

import javax.annotation.*;
import java.lang.annotation.*;

/**
 * 类 名: Main
 * 描 述: 测试组合注解
 * @author: jiaYao
 */
public class Main {

    public static void main(String[] args) {

        Class<UserService> classz = UserService.class;
        getAnnos(classz);
    }

    /**
     * interface java.lang.annotation.Documented 等 存在循环,导致内存溢出,所以需要排除java的源注解
     * @param classz
     */
    private static void getAnnos(Class<?> classz){
        Annotation[] annotations = classz.getAnnotations();
        for (Annotation annotation : annotations) {
            if (annotation.annotationType() != Deprecated.class &&
                    annotation.annotationType() != SuppressWarnings.class &&
                    annotation.annotationType() != Override.class &&
                    annotation.annotationType() != PostConstruct.class &&
                    annotation.annotationType() != PreDestroy.class &&
                    annotation.annotationType() != Resource.class &&
                    annotation.annotationType() != Resources.class &&
                    annotation.annotationType() != Generated.class &&
                    annotation.annotationType() != Target.class &&
                    annotation.annotationType() != Retention.class &&
                    annotation.annotationType() != Documented.class &&
                    annotation.annotationType() != Inherited.class
                    ) {
                if (annotation.annotationType() == MyComponent.class){
                    System.out.println(" 存在注解 @MyComponent ");
                }else{
                    getAnnos(annotation.annotationType());
                }
            }
        }
    }
}

 

通过程序的输出语句,我们在控制台可以看到有输出:

 存在注解 @MyComponent

 

通过这种方式,我们就可以实现组合注解功能了,这样我们在自定义注解时,可以将很多具有公共属性的注解进行提取,通过注解继承的方式完成组合注解的实现了;

是不是很简单~~~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章