跳到正文
Elaine Blog
返回

注解、反射与动态代理

Java 基础

Spring、ORM 和测试框架常在运行时读取类型信息并包装方法调用。理解注解、反射和代理后,你能判断框架行为来自普通 Java 机制,而不是“魔法”。

Table of contents

Open Table of contents

注解只是元数据

**注解(Annotation)**是附着在代码元素上的结构化元数据。它本身不会执行行为;必须有编译器、框架或你的代码读取它。

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface 记录耗时 {}

RUNTIME 表示运行时仍可通过反射读取;METHOD 限制只能标记方法。如果只是源码检查,可用 SOURCE,不必把元数据 留到运行时。

用动态代理实现拦截

import java.lang.reflect.*;

interface 问候服务 { String 问候(String name); }

final class 默认问候服务 implements 问候服务 {
    @记录耗时 public String 问候(String name) { return "你好," + name; }
}

static <T> T 创建代理(Class<T> type, T target) {
    Object proxy = Proxy.newProxyInstance(type.getClassLoader(), new Class<?>[]{type},
        (ignored, method, args) -> {
            Method implementation = target.getClass().getMethod(method.getName(), method.getParameterTypes());
            long started = System.nanoTime();
            try {
                return implementation.invoke(target, args);
            } catch (InvocationTargetException e) {
                throw e.getCause();
            } finally {
                if (implementation.isAnnotationPresent(记录耗时.class)) {
                    System.out.println(method.getName() + " 耗时(ns): " + (System.nanoTime() - started));
                }
            }
        });
    return type.cast(proxy);
}

**反射(Reflection)**允许程序在运行时检查类、方法和注解。**动态代理(Dynamic Proxy)**创建一个实现指定接口的代理 对象,把方法调用转发给 InvocationHandler。JDK 动态代理只能代理接口;代理具体类通常需要字节码生成库。

最小依赖注入思路

依赖注入容器的核心步骤并不神秘:扫描候选类型、检查构造器、递归创建依赖、缓存实例。真正困难的是循环依赖、作用域、 生命周期、并发安全和错误诊断。因此学习示例可以几十行,生产容器不应该重复自研。

反射的边界

下一步

阅读时间、金额、精度与序列化,处理跨进程数据时避免隐式假设。


分享这篇文章:

上一篇
文件、网络与 NIO 基础
下一篇
时间、金额、精度与序列化