当前位置: 首页 > news >正文

深入理解 Java 的反射、注解与动态代理


在 Java 的高级特性中,反射(Reflection)注解(Annotation)动态代理(Dynamic Proxy) 是构建框架、实现 AOP、ORM 等重要机制的基础。本文将逐一详解这三大特性,并辅以代码示例,帮助你在实际项目中更好地理解和运用它们。


一、反射:运行时的自省与操作能力

1.1 反射是什么?

反射是 Java 提供的一种机制,允许程序在运行时加载、探查以及操作类的结构(如方法、构造器、字段等)。

1.2 基本 API 使用

public class Person {private String name;private int age;public Person() {}public Person(String name) {this.name = name;}private void sayHello() {System.out.println("Hello, my name is " + name);}
}
获取类对象的三种方式:
Class<?> clazz1 = Person.class;
Class<?> clazz2 = new Person().getClass();
Class<?> clazz3 = Class.forName("your.package.Person");
获取构造器并实例化:
Constructor<?> constructor = clazz1.getConstructor(String.class);
Person p = (Person) constructor.newInstance("Tom");
获取字段和方法:
Field nameField = clazz1.getDeclaredField("name");
nameField.setAccessible(true); // 解除私有访问限制
nameField.set(p, "Jerry");
System.out.println(nameField.get(p)); // 输出 JerryMethod method = clazz1.getDeclaredMethod("sayHello");
method.setAccessible(true);
method.invoke(p); // 输出 Hello, my name is Jerry

二、注解:元数据的声明机制

2.1 注解的定义与使用

注解是 Java 5 引入的一种元数据机制,常用于代码标记、配置或提供信息给框架。

自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecution {String value() default "执行方法";
}
使用注解:
public class UserService {@LogExecution("执行用户注册")public void register(String name) {System.out.println(name + " registered.");}
}
解析注解:
public class AnnotationProcessor {public static void main(String[] args) throws Exception {Method method = UserService.class.getMethod("register", String.class);if (method.isAnnotationPresent(LogExecution.class)) {LogExecution log = method.getAnnotation(LogExecution.class);System.out.println("日志: " + log.value());}}
}

输出:日志: 执行用户注册


三、动态代理:运行时生成接口实现

3.1 动态代理的应用场景

Java 的动态代理允许你在运行时生成一个实现了指定接口的类。常用于:

  • AOP 编程(如日志、事务处理)
  • RPC 框架(如 Dubbo)
  • 装饰器模式的实现

3.2 使用 JDK 动态代理

定义接口与实现:
public interface HelloService {void sayHello(String name);
}public class HelloServiceImpl implements HelloService {public void sayHello(String name) {System.out.println("Hello, " + name);}
}
创建代理处理器:
public class LogInvocationHandler implements InvocationHandler {private final Object target;public LogInvocationHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法调用前: " + method.getName());Object result = method.invoke(target, args);System.out.println("方法调用后: " + method.getName());return result;}
}
创建代理对象并调用:
public class ProxyDemo {public static void main(String[] args) {HelloService service = new HelloServiceImpl();HelloService proxyInstance = (HelloService) Proxy.newProxyInstance(service.getClass().getClassLoader(),service.getClass().getInterfaces(),new LogInvocationHandler(service));proxyInstance.sayHello("Alice");}
}

输出:

方法调用前: sayHello
Hello, Alice
方法调用后: sayHello

四、注解 + 反射 + 代理:模拟 AOP 切面编程

结合三者,我们可以模拟一个 AOP 实现:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {String value() default "调用方法";
}public interface UserService {@Log("用户登录")void login(String username);
}public class UserServiceImpl implements UserService {public void login(String username) {System.out.println(username + " 登录系统");}
}public class AOPHandler implements InvocationHandler {private final Object target;public AOPHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.isAnnotationPresent(Log.class)) {Log log = method.getAnnotation(Log.class);System.out.println("[AOP日志] " + log.value());}return method.invoke(target, args);}
}public class AOPDemo {public static void main(String[] args) {UserService target = new UserServiceImpl();UserService proxy = (UserService) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new AOPHandler(target));proxy.login("admin");}
}

输出:

[AOP日志] 用户登录
admin 登录系统

五、总结

特性用途常用 API/关键词
反射运行时探查与操作类结构Class、Method、Field、Constructor
注解元数据标注@interface、@Retention、@Target
动态代理运行时增强接口逻辑、AOP 实现Proxy.newProxyInstance、InvocationHandler

相关文章:

  • 2025新高考二卷选择题第一题题解
  • LangChain4j 1.x 核心源码剖析-基础篇
  • 【项目实训项目博客】用户使用手册
  • Secs/Gem第十二讲(基于secs4net项目的ChatGpt介绍)
  • 【第四十八周】HippoRAG 2 复现与分析(二):索引阶段代码分析
  • 嵌入式学习笔记 - freeRTOS为什么中断中不能使用互斥量
  • 使用自定义模板的方式批量切割图片。
  • 从零开始编写Mcp Server,发布上线,超简单极速入门
  • Amazon RDS on AWS Outposts:解锁本地化云数据库的混合云新体验
  • 循环神经网络(RNN):从理论到翻译
  • 标准代码项目开发流程学习指南
  • leetcode Top100 238. 除自身以外数组的乘积|数组系列
  • 【Ragflow】27.RagflowPlus(v0.4.1):小版本迭代,问题修复与功能优化
  • 高保真组件库:单选复选
  • 为什么需要Redis分布式锁?在哪些微服务场景下会用到?
  • 【C/C++】namespace + macro混用场景
  • 解决SQL Server SQL语句性能问题(9)——SQL语句改写(2)
  • gitee....
  • split方法
  • 如果在main中抛出异常,该如何处理
  • 中山手机网站建设价格/色盲怎么治疗
  • 网站建设 6万/云搜索app
  • 安徽工程建设信息网站/软文云
  • 苏州企业建设网站价格/免费的云服务器有哪些
  • 做神马网站优化快速排名软件/国家培训网官网
  • 深圳福田有哪些公司/推广优化网站排名