java @注解;反射可读取注解然后执行其他方法

文章目录

      • 注解是什么
        • 扫描注解并做处理
        • Class 类
      • spring

注解是什么

Java 中的注解本质上是:

一种标记(标签),用来给代码添加额外的信息。其字节码保存在 .class 文件中,并可被反射机制读取。

定义 Component 注解:

@Target(ElementType.TYPE)			// 可以加载类(TYPE)上
@Retention(RetentionPolicy.RUNTIME)	// 运行时保留 (可反射读取)
public @interface Component {
}

@Target 和 @Retention 是元注解,用来修饰定义的注解。

扫描注解并做处理

自定义注解:

@Retention(RetentionPolicy.RUNTIME) // 必须设置为 RUNTIME,否则反射读不到
@Target({ElementType.TYPE, ElementType.METHOD}) // 可以标记在类或方法上
public @interface MyAnnotation {
    String value() default "默认值";
    int priority() default 0;
}

用注解标记类和方法:

@MyAnnotation(value = "这是一个类注解", priority = 1)
public class MyClass {

    @MyAnnotation(value = "方法注解A", priority = 2)
    public void methodA() {
        System.out.println("执行方法A");
    }

    @MyAnnotation(value = "方法注解B", priority = 3)
    public void methodB() {
        System.out.println("执行方法B");
    }
}

通过反射(Reflection)可以在运行时扫描类和方法的注解,并读取注解中的属性值:

import java.lang.reflect.Method;

public class AnnotationScanner {

    public static void main(String[] args) throws ClassNotFoundException {
        // 加载目标类
        Class clazz = Class.forName("MyClass"); // 替换为你的类全限定名

        // 扫描类上的注解
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation classAnnotation = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("类上的注解信息:");
            System.out.println("value: " + classAnnotation.value());
            System.out.println("priority: " + classAnnotation.priority());
            System.out.println("---------------------");
        }

        // 扫描所有方法的注解
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
                System.out.println("方法 " + method.getName() + " 的注解信息:");
                System.out.println("value: " + methodAnnotation.value());
                System.out.println("priority: " + methodAnnotation.priority());
                System.out.println("---------------------");
            }
        }
    }
}
Class 类

Class类是 Java 反射机制的核心组成部分。每一个被 Java 虚拟机(JVM)加载的类,都会有唯一的Class对象与之对应。借助这个Class对象 可以在运行时获取该类的各种信息(像类的结构、方法、字段等),还能对类进行实例化操作以及调用其方法。

获取Class对象:

// 方式一:使用类名的.class属性
Class clazz1 = MyClass.class;

// 方式二:通过对象的getClass()方法
MyClass obj = new MyClass();
Class clazz2 = obj.getClass();

// 方式三:利用全限定类名动态加载(你提供的代码采用的就是这种方式)
Class clazz3 = Class.forName("com.example.MyClass");

使用:

//对上文的Class类型的 clazz 对象:

// 获得构造器
Constructor constructor = clazz.getDeclaredConstructor();
MyClass instance = (MyClass) constructor.newInstance();

// 检查注解
if (clazz.isAnnotationPresent(MyAnnotation.class)) {
    MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);
    // 对注解进行处理
}

// 【反射】获取方法,字段:
Method[] methods = clazz.getMethods();          // 获取所有公共方法
Field[] fields = clazz.getDeclaredFields();    // 获取所有声明的字段
Constructor[] constructors = clazz.getConstructors(); // 获取所有公共构造函数

spring

我们往往想执行一些类的方法,这需要类对象实例。
如果直接调用 static 方法,不能多态。
而每次都new,又有所消耗,毕竟只调用方法。

那就需要我们去管理这些服务类对象实例 —— spring 就是做这个的!

你不再手动创建对象,而是告诉 Spring:我要这个类,它会帮你“注入”一个已经创建好的对象:

	@Autowired
	private UserService userService;

我们可以把 Spring 的 IOC 容器想象成一个 对象工厂 + 哈希表缓存。每个类被创建好之后就放进这个表里,以后要用的时候就直接拿,不需要 new!

解决了频繁创建带有依赖的复杂对象。

你可能感兴趣的:(2025,-,java,java,开发语言)