今天在自定义注解的时候,原计划实现一个类似于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
通过这种方式,我们就可以实现组合注解功能了,这样我们在自定义注解时,可以将很多具有公共属性的注解进行提取,通过注解继承的方式完成组合注解的实现了;
是不是很简单~~~