Java 反射(Reflection)与注解(Annotation)的结合是 Java 框架开发中非常常见的设计方式。通过反射,可以在运行时动态获取类、方法、字段等信息,而注解允许为这些元素添加元数据。结合起来,开发者可以在运行时解析注解,并基于注解信息执行相应的逻辑。
反射与注解结合的常见场景
- 依赖注入框架(如 Spring):框架通过反射扫描类和方法,识别注解来管理 Bean 的创建和依赖注入。
- ORM 框架(如 Hibernate):通过注解标识实体类的属性,反射解析这些注解,实现数据库表与对象的映射。
- AOP(面向切面编程):通过注解定义切点(Pointcut)等信息,利用反射在运行时动态织入代码。
使用步骤
-
定义注解
首先定义自定义注解。注解通常带有一些元信息,用来标记类、方法、字段等。// MyAnnotation.java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String value(); }
@Retention(RetentionPolicy.RUNTIME)
:确保注解在运行时可用。@Target(ElementType.METHOD)
:指定注解可以应用于方法。
-
在代码中使用注解
之后在类、方法等处应用这个注解。// ReflectionTemp.java package Annotation; public class ReflectionTemp { public ReflectionTemp(String testName) { this.testName = testName; } private String testName; @MyAnnotation(value = "testReflection") public String getTestName(){ System.out.println("ReflectionTemp中testName值为: " + testName ); return testName; } }
-
通过反射解析注解
使用反射在运行时解析注解信息,并基于注解执行逻辑。package Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class AnnotationProcessor { public static void main(String[] args) throws Exception { // 获取 TestClass 类 Class<?> clazz = ReflectionTemp.class; // 获取类中的所有方法 Method[] methods = clazz.getDeclaredMethods(); // 获取构造方法 Constructor<?> constructor =clazz.getConstructor(String.class); // 遍历方法,检查注解 for (Method method : methods) { if (method.isAnnotationPresent(MyAnnotation.class)) { // 获取注解 MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); String value = annotation.value(); System.out.println("找到有MyAnnotation注解方法: " + method.getName() + ", MyAnnotation注解的值为: " + annotation.value()); // 构造方法构建对象,使用test1111 Object newInstance = constructor.newInstance("test1111"); // 通过反射调用该方法 System.out.println(" 没修改时:"); method.invoke(newInstance); // 使用Field 修改具体属性 Field field = clazz.getDeclaredField("testName"); field.setAccessible(true); field.set(newInstance,value); field.setAccessible(false); System.out.println(" 修改时:"); // 修改具体属性 再次反射调用该方法 method.invoke(newInstance); } } } }
// 运行结果
找到有MyAnnotation注解方法: getTestName, MyAnnotation注解的值为: testReflection
没修改时:
ReflectionTemp中testName值为: test1111
修改时:
ReflectionTemp中testName值为: testReflection
关键点总结
-
获取类或方法的注解
通过反射,使用isAnnotationPresent
判断是否存在特定注解,使用getAnnotation
获取注解对象。 -
注解中的属性值
注解可以定义属性值(如value()
),通过反射可以获取这些属性值,并基于此执行不同的逻辑。 -
运行时处理
反射结合注解主要用于框架开发,允许在运行时动态扫描注解并执行相应逻辑,例如自动注入依赖、事务管理、拦截器等。
常见应用场景
- 框架配置:通过注解标注配置类和方法,框架在运行时扫描并加载配置。
- 自动化处理:通过注解标识需要特殊处理的方法或类,如事务管理、权限控制、日志记录等。
Java 反射与注解的结合使得程序具备高度的灵活性,广泛应用于各种框架与工具的开发中。