注解继承的说明


1、首先要想Annotation能被继承,需要在注解定义的时候加上@Inherited,并且如果要被反射应用的话,就需要还有个事@Retention(RetentionPolicy.RUNTIME)标识

2、JDK文档中说明的是:只有在类上应用Annotation才能被继承,而实际应用结果是:除了类上应用的Annotation能被继承外,没有被重写的方法的Annotation也能被继承;

3、当方法被重写后,Annotation不会被继承

4、Annotation的继承不能应用在接口上


Spring事务注解@Transactional

@Transactional 可以作用于接口、接口方法、类以及类方法上。但是 Spring 小组建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的(从上面的Spring AOP 事务增强可以看出,就是针对方法的)。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

Spring 的注解继承

我们常见的注解都继承了注解@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());
                }
            }
        }
    }
}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐