注解学习与实战(一)

1、注解概念

首先什么是注解,先看官方说明,它提供了一种安全的类似注释的机制,用来将任何的信息和元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。为程序的元素(类、方法、成员变量)加上更直观、更明了的说明,这些说明信息与程序的业务逻辑无关,并且供制定的工具或框架使用。Annotion像一种修饰符一样,应用于包、类型、构造方法、方法、成员变量、参数及本地变量的声明语句中。

通俗一点就是给人贴上标签、下定义,把某些属性附加给对象,提供一种安全的类似注释的机制,用来将任何信息或元数据(metadata)与程序元素进行关联。

2、元注解

为了实现自定义注解,首先得了解元注解。源注解就是专门注解其他的注解。

2.1 java.lang.annontation提供了5中元注解。

  • @Target() 注解的作用目标, 用于描述注解的使用范围(即:被描述的注解可以用在什么地方) @Target(ElementType.TYPE)——接口、类、枚举、注解

  • @Retention: 注解的生命周期,什么时候使用该注解

    • RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
    • RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
    • RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。我们自定义注解通常使用这种方法。
  • @Document : 说明该注解被包含在javadoc中

  • @Inherited: 允许子类可以继承父类中的该注解

  • @Repetable : 指定注解可重复使用

2.2 @Import

额外重要的注解 @Import :是用来导入配置类或者一些需要前置加载的类.

3、注解实战

下面是我平时项目中使用的自定义注解,主要实现的功能就是,Spring启动的时候,根据注解配置的内容来实现启动哪种配置类。

3.1 自定义注解

定义的注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({EnableRadarImportSelector.class})
public @interface EnableRadar {
    RadarOpenStrategy strategy();
}

定义类

public enum RadarOpenStrategy {
    RADAR_24G,
    RADAR_77G,
    RADAR_BOTH;

    private RadarOpenStrategy() {
    }
}

实现逻辑

public class EnableRadarImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        Map<String, Object> attributes = metadata.getAnnotationAttributes(EnableRadar.class.getName());
        assert attributes != null;
        String strategy = attributes.get("strategy").toString();
        switch (strategy){
            case "RADAR_24G":
                return new String[] {Radar24gConfiguration.class.getName()};
            case "RADAR_77G":
                return new String[] {Radar77gConfiguration.class.getName()};
            default:
                return new String[] {Radar24gConfiguration.class.getName(), Radar77gConfiguration.class.getName()};
        }
    }
}

主类

@SpringBootApplication
@Slf4j
@EnableRadar(strategy = RadarOpenStrategy.RADAR_77G) //注解的使用
@MapperScan("com.example.mapper")
public class LouyusdkApplication {

    public static void main(String[] args) {
        TimeZone.setDefault(TimeZone.getTimeZone("Asia/Shanghai"));
        System.setProperty("spring.devtools.restart.enabled", "false");
        ConfigurableApplicationContext context = SpringApplication.run(LouyusdkApplication.class, args);
        Map<String, Object> beansWithAnnotation = context.getBeansWithAnnotation(EnableRadar.class); //得到拥有该注解的Bean
         for (Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()) {
            System.out.println("Current Class: "+ entry.getKey());
            Object handler = entry.getValue();
            EnableRadar annotation = handler.getClass().getAnnotation(EnableRadar.class);
            System.out.println("RadarOpenStrategy: "+ annotation.strategy());
        }
    }
}

输出界面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AL7KauHw-1648796437211)(G:\技术积累\Spring学习.assets\image-20220401143258560.png)]

3.2 注解类高级使用

可以从主类代码中看到,我们可以在代码中动态的获取到注解的内容和拥有注解的类,有了这些内容,我们可以实现一些高级功能,比如根据注解的内容来实现一些代码逻辑。

getBeansWithAnnotation方法

源码解释: Find all beans which are annotated with the supplied Annotation type, returning a Map of bean names with corresponding bean instances.Note that this method considers objects created by FactoryBeans, which means that FactoryBeans will get initialized in order to determine their object type.

解释:返回所有被这个注解生命的类,返回的是一个Map<String, Object>类型, Map的第一个类名,第二个就是这个类

getAnnotation方法

源码的英文解释 Returns this element’s annotation for the specified type if such an annotation is present, else null.

通俗的解释,返回这个类上面定义的注解类,同时可以使用注解定义的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值