Java反射注解

注解

package com.qyc;/**
 * @ClassName: annotation
 * @Description:
 * @Author: qiangyuecheng
 * @Date: 2021/3/9 7:44 下午
 */

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *@ClassName: annotation
 *@Description:
 *@Author: qiangyuecheng
 *@Date: 2021/3/9 7:44 下午
 */

/**
 * 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。
 * Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,
 * 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 RententionPolicy使用。RetentionPolicy有3个值:CLASS  RUNTIME   SOURCE
 * 按生命周期来划分可分为3类:
 * 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;
 * 2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
 * 3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
 * 这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
 * 那怎么来选择合适的注解生命周期呢?
 * 首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。
 * 一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解,比如@Deprecated使用RUNTIME注解
 * 如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;
 * 如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,使用SOURCE 注解。
 *
 * 注解@Override用在方法上,当我们想重写一个方法时,在方法上加@Override,当我们方法的名字出错时,编译器就会报错
 * 注解@Deprecated,用来表示某个类或属性或方法已经过时,不想别人再用时,在属性和方法上用@Deprecated修饰
 * 注解@SuppressWarnings用来压制程序中出来的警告,比如在没有用泛型或是方法已经过时的时候
 */

/*
@Target:注解的作用目标

@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.TYPE})
public @interface ZhuJie {
    String names() default "123";
}

Service层

package com.qyc.service;/**
 * @ClassName: Service01
 * @Description:
 * @Author: qiangyuecheng
 * @Date: 2021/3/11 12:15 上午
 */

public class Service01 {
    public void show(){
        System.out.println(" service.show() ");
    }
}

 

 

Controller层

package com.qyc.conteoller;/**
 * @ClassName: Controller01
 * @Description:
 * @Author: qiangyuecheng
 * @Date: 2021/3/9 7:51 下午
 */

import com.qyc.ZhuJie;
import com.qyc.service.Service01;
import org.springframework.stereotype.Controller;

@Controller
public class Controller01 {
    @ZhuJie
    private Service01 service01;

    @ZhuJie(names = "456")
    private Service01 service02;


    public void shows(){
        service01.show();
    }
}

 

test层

package com.test;/**
 * @ClassName: Test01
 * @Description:
 * @Author: qiangyuecheng
 * @Date: 2021/3/11 12:12 上午
 */

import com.qyc.ZhuJie;
import com.qyc.conteoller.Controller01;
import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.util.stream.Stream;

public class Test01 {

    @Test
    public void test001(){
        Controller01 controller01 = new Controller01();
        Class<? extends Controller01> clazz = controller01.getClass();
        controller01.getClass();
        Stream.of(clazz.getDeclaredFields()).forEach(field -> {
            String name = field.getName();
            System.out.println("name = " + name);
            ZhuJie zhuJie = field.getAnnotation(ZhuJie.class);
            System.out.println("zhuJie = " + zhuJie.names());
            if(zhuJie !=null){
                field.setAccessible(true);
                Class<?> type = field.getType();
                System.out.println("type = " + type);
                try {
                    Object object = type.getConstructor().newInstance();
                    field.set(controller01,object);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
            controller01.shows();
        });
    }

}

执行结果

name = service01
zhuJie = 123
type = class com.qyc.service.Service01
 service.show() 
name = service02
zhuJie = 456
type = class com.qyc.service.Service01
 service.show() 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值