1. Java反射机制与注解的本质解析
在Java开发领域,反射机制和注解是构建灵活、可扩展系统的两大基石。我至今记得第一次通过反射动态调用方法时那种"原来还能这样"的震撼感,以及使用注解简化配置后代码变得多么清爽。这两种技术本质上都属于元编程范畴——即编写能够操作其他代码的代码。
反射机制的核心在于java.lang.reflect包,它允许我们在运行时获取类的完整结构信息。Class对象是这个机制的关键入口,通过它我们能获取:
- 构造方法(Constructor)
- 成员变量(Field)
- 方法(Method)
- 注解(Annotation)
而注解则是JDK5引入的元数据机制,以@符号为标志。常见的如@Override、@Deprecated等内置注解,以及我们可以自定义的注解类型。注解本身不包含业务逻辑,但可以通过反射读取并触发相应行为。
关键理解:反射是"运行时自省"能力,注解是"代码标记"机制,二者结合能实现声明式编程范式
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 反射机制深度剖析
2.1 反射核心API实战
让我们通过具体代码看看反射的基本用法。假设有一个User类:
java复制public class User {
private String name;
public User() {}
public User(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello, " + name);
}
}
获取Class对象的三种方式:
java复制// 1. 通过类名.class
Class<User> clazz1 = User.class;
// 2. 通过对象.getClass()
User user = new User();
Class<? extends User> clazz2 = user.getClass();
// 3. 通过Class.forName()
Class<?> clazz3 = Class.forName("com.example.User");
动态创建实例:
java复制// 使用无参构造
User user1 = clazz1.newInstance();
// 使用有参构造
Constructor<User> constructor = clazz1.getConstructor(String.class);
User user2 = constructor.newInstance("John");
方法调用示例:
java复制Method method = clazz1.getMethod("sayHello");
method.invoke(user2); // 输出:Hello, John
2.2 反射性能优化方案
反射虽然灵活,但性能开销较大。实测对比直接调用和反射调用,性能差距可达数倍。优化方案包括:
- 缓存反射对象:将获取的Method、Field等对象缓存复用
java复制private static final Method SAY_HELLO_METHOD;
static {
try {
SAY_HELLO_METHOD = User.class.getMethod("sayHello");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
- 使用MethodHandle(JDK7+):
java复制MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.findVirtual(User.class, "sayHello",
MethodType.methodType(void.class));
mh.invokeExact(user);
- setAccessible(true)慎用:虽然能突破private限制,但会破坏封装性
3. 注解机制全面解析
3.1 注解类型定义与使用
自定义注解示例:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {
String value() default "";
}
关键元注解说明:
- @Retention:注解保留策略(SOURCE/CLASS/RUNTIME)
- @Target:注解适用目标(TYPE/FIELD/METHOD等)
- @Documented:是否包含在Javadoc中
- @Inherited:是否允许子类继承
3.2 注解处理实战
通过反射处理注解的典型模式:
java复制Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(LogExecutionTime.class)) {
LogExecutionTime annotation = method.getAnnotation(LogExecutionTime.class);
String tag = annotation.value();
long start = System.nanoTime();
method.invoke(target);
long duration = System.nanoTime() - start;
System.out.printf("[%s]执行耗时:%d ns%n", tag, duration);
}
}
4. 动态编程高级应用
4.1 动态代理模式
结合反射实现动态代理的经典案例:
java复制public class DebugProxy implements InvocationHandler {
private final Object target;
public DebugProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Object result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
public static <T> T createProxy(T target, Class<T> interfaceType) {
return (T) Proxy.newProxyInstance(
interfaceType.getClassLoader(),
new Class<?>[] { interfaceType },
new DebugProxy(target)
);
}
}
4.2 注解驱动开发
现代框架如Spring的核心机制:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String value() default "";
}
// 模拟容器扫描
public class Container {
private Map<String, Object> beans = new HashMap<>();
public void scan(String basePackage) {
// 扫描类路径(简化版)
Class<?> clazz = Class.forName(basePackage + ".UserService");
if (clazz.isAnnotationPresent(Component.class)) {
Component comp = clazz.getAnnotation(Component.class);
String beanName = comp.value().isEmpty() ?
clazz.getSimpleName() : comp.value();
beans.put(beanName, clazz.newInstance());
}
}
}
5. 实战中的避坑指南
5.1 反射常见问题
-
NoSuchMethodException:
- 检查方法名是否拼写正确
- 确认参数类型是否匹配(int.class ≠ Integer.class)
- 注意重载方法的参数顺序
-
IllegalAccessException:
- 检查字段/方法访问权限
- 必要时使用setAccessible(true),但需考虑安全影响
-
性能热点:
- 避免在循环中使用反射
- 对高频调用路径考虑字节码增强方案(如ASM)
5.2 注解使用陷阱
-
注解继承问题:
- 默认情况下注解不会被继承
- 需要显式使用@Inherited元注解
-
注解属性限制:
- 属性类型只能是基本类型、String、Class、枚举、注解或它们的数组
- 不能使用null作为默认值
-
重复注解处理:
- JDK8前需要通过容器注解模式实现
java复制@Retention(RetentionPolicy.RUNTIME) public @interface Tags { Tag[] value(); } @Retention(RetentionPolicy.RUNTIME) @Repeatable(Tags.class) public @interface Tag { String value(); }
6. 现代Java生态中的应用
6.1 Spring框架中的反射
Spring的核心机制之一就是通过反射实现依赖注入:
java复制// 简化的依赖注入实现
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
Object dependency = context.getBean(field.getType());
field.setAccessible(true);
field.set(bean, dependency);
}
}
6.2 Lombok原理剖析
Lombok通过注解处理API(APT)在编译期修改AST:
- 定义注解:
java复制@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
boolean staticConstructor() default false;
}
- 注解处理器骨架:
java复制@SupportedAnnotationTypes("lombok.*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class LombokProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
// 处理AST,生成getter/setter等方法
}
}
6.3 测试框架中的应用
JUnit的核心运行机制:
java复制public class TestRunner {
public static void run(Class<?> testClass) throws Exception {
Object testInstance = testClass.newInstance();
for (Method method : testClass.getMethods()) {
if (method.isAnnotationPresent(Test.class)) {
try {
method.invoke(testInstance);
} catch (InvocationTargetException e) {
if (e.getCause() instanceof AssertionError) {
// 测试失败处理
}
}
}
}
}
}
7. 安全考量与最佳实践
7.1 反射安全限制
-
安全管理器:
java复制SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new ReflectPermission("suppressAccessChecks")); } -
模块系统限制(JDK9+):
- 需要opens指令开放反射权限
- 建议在module-info.java中精确控制开放范围
7.2 注解处理规范
-
编译期处理:
- 实现Processor接口处理SOURCE级别注解
- 通过RoundEnvironment获取注解元素
-
运行时处理:
- 优先使用Spring的AnnotationUtils
- 注意注解代理对象的equals/hashCode特殊性
8. 性能对比与选型建议
8.1 技术方案对比
| 场景 | 反射方案 | 注解方案 | 混合方案 |
|---|---|---|---|
| 简单配置 | 过度 | 适合 | 过度 |
| 动态扩展 | 适合 | 有限 | 推荐 |
| AOP实现 | 基础 | 声明式 | 最佳 |
| 框架基础设施 | 必须 | 推荐 | 必须 |
8.2 实际项目经验
在电商平台开发中,我们这样应用这些技术:
- 订单状态机:通过注解定义状态转换规则
java复制@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Transition {
String from();
String to();
}
// 使用示例
public class OrderService {
@Transition(from = "CREATED", to = "PAID")
public void pay(Order order) {
// 支付逻辑
}
}
- 动态权限检查:反射+注解实现
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequirePermission {
String value();
}
public class SecurityInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
if (method.isAnnotationPresent(RequirePermission.class)) {
String perm = method.getAnnotation(RequirePermission.class).value();
if (!checkPermission(perm)) {
throw new SecurityException("Permission denied");
}
}
return invocation.proceed();
}
}
- 数据校验:结合注解进行声明式校验
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Valid {
int minLength() default 0;
int maxLength() default Integer.MAX_VALUE;
String regex() default "";
}
public class Validator {
public static void validate(Object obj) throws IllegalAccessException {
for (Field field : obj.getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Valid.class)) {
Valid valid = field.getAnnotation(Valid.class);
field.setAccessible(true);
Object value = field.get(obj);
// 执行校验逻辑
}
}
}
}
这些技术组合使用时,需要注意版本兼容性问题。特别是在模块化项目中(JDK9+),需要正确配置module-info.java:
java复制module com.example {
requires java.base;
requires java.compiler;
requires java.logging;
// 允许反射访问
opens com.example.core to spring.core;
// 导出注解包
exports com.example.annotations;
}
对于需要高性能的场景,可以考虑预先生成反射访问类。比如使用Byte Buddy库:
java复制Class<?> dynamicType = new ByteBuddy()
.subclass(Object.class)
.method(ElementMatchers.named("toString"))
.intercept(FixedValue.value("Hello World!"))
.make()
.load(getClass().getClassLoader())
.getLoaded();
在微服务架构中,我们经常需要处理接口的版本兼容。通过注解可以优雅地实现:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ApiVersion {
int from() default 1;
int to() default Integer.MAX_VALUE;
}
public class VersionAwareProxy implements InvocationHandler {
private final Object target;
private final int clientVersion;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method targetMethod = findTargetMethod(method);
if (targetMethod == null) return null;
ApiVersion version = targetMethod.getAnnotation(ApiVersion.class);
if (version != null && (clientVersion < version.from() || clientVersion > version.to())) {
throw new UnsupportedOperationException("API version not supported");
}
return targetMethod.invoke(target, args);
}
private Method findTargetMethod(Method method) {
// 实现方法查找逻辑
}
}
对于测试代码,反射和注解能极大提升可维护性。比如参数化测试:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TestCase {
String input();
String expected();
}
public class StringUtilsTest {
@TestCase(input = "hello", expected = "HELLO")
@TestCase(input = "Java", expected = "JAVA")
public void testToUpperCase(String input, String expected) {
assertEquals(expected, StringUtils.toUpperCase(input));
}
public static void main(String[] args) throws Exception {
Method testMethod = StringUtilsTest.class.getMethod("testToUpperCase", String.class, String.class);
TestCase[] cases = testMethod.getAnnotationsByType(TestCase.class);
for (TestCase tc : cases) {
String result = (String) testMethod.invoke(
new StringUtilsTest(),
tc.input(),
tc.expected()
);
System.out.printf("Test case: input=%s, result=%s%n", tc.input(), result);
}
}
}
在Android开发中,反射和注解同样发挥着重要作用。比如ButterKnife的实现原理:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface BindView {
int value();
}
public class ButterKnife {
public static void bind(Activity activity) {
Class<?> clazz = activity.getClass();
for (Field field : clazz.getDeclaredFields()) {
BindView bindView = field.getAnnotation(BindView.class);
if (bindView != null) {
try {
View view = activity.findViewById(bindView.value());
field.setAccessible(true);
field.set(activity, view);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
对于需要处理JSON的场景,可以定义自己的序列化注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JsonField {
String name() default "";
boolean ignore() default false;
String format() default "";
}
public class JsonSerializer {
public static String toJson(Object obj) throws IllegalAccessException {
StringBuilder json = new StringBuilder("{");
boolean first = true;
for (Field field : obj.getClass().getDeclaredFields()) {
JsonField jsonField = field.getAnnotation(JsonField.class);
if (jsonField != null && jsonField.ignore()) continue;
String fieldName = jsonField != null && !jsonField.name().isEmpty() ?
jsonField.name() : field.getName();
field.setAccessible(true);
Object value = field.get(obj);
if (!first) json.append(",");
first = false;
json.append("\"").append(fieldName).append("\":");
if (value instanceof String) {
json.append("\"").append(value).append("\"");
} else if (value instanceof Date && jsonField != null
&& !jsonField.format().isEmpty()) {
SimpleDateFormat sdf = new SimpleDateFormat(jsonField.format());
json.append("\"").append(sdf.format(value)).append("\"");
} else {
json.append(value);
}
}
return json.append("}").toString();
}
}
在数据库访问层,可以定义ORM注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
String tableName();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
String name() default "";
boolean primaryKey() default false;
boolean autoIncrement() default false;
}
public class SimpleORM {
public static <T> String buildInsertSQL(Class<T> clazz) {
if (!clazz.isAnnotationPresent(Entity.class)) {
throw new IllegalArgumentException("Class is not an entity");
}
Entity entity = clazz.getAnnotation(Entity.class);
StringBuilder sql = new StringBuilder("INSERT INTO ")
.append(entity.tableName()).append(" (");
StringBuilder values = new StringBuilder(" VALUES (");
boolean first = true;
for (Field field : clazz.getDeclaredFields()) {
Column column = field.getAnnotation(Column.class);
if (column == null || column.autoIncrement()) continue;
String columnName = column.name().isEmpty() ?
field.getName() : column.name();
if (!first) {
sql.append(", ");
values.append(", ");
}
first = false;
sql.append(columnName);
values.append("?");
}
return sql.append(")").append(values.append(")")).toString();
}
}
对于需要处理HTTP请求的场景,可以模拟简单的Web框架:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequestMapping {
String path();
String method() default "GET";
}
public class MiniWebFramework {
private Map<String, Method> routeHandlers = new HashMap<>();
public void registerController(Object controller) {
for (Method method : controller.getClass().getMethods()) {
RequestMapping mapping = method.getAnnotation(RequestMapping.class);
if (mapping != null) {
String key = mapping.method() + ":" + mapping.path();
routeHandlers.put(key, method);
}
}
}
public Object handleRequest(String httpMethod, String path, Object controller) throws Exception {
String key = httpMethod + ":" + path;
Method handler = routeHandlers.get(key);
if (handler == null) {
throw new RuntimeException("No handler found");
}
return handler.invoke(controller);
}
}
在缓存处理方面,可以定义缓存注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Cacheable {
String keyPrefix() default "";
int ttl() default 60; // seconds
}
public class CacheInterceptor implements InvocationHandler {
private final Object target;
private final Map<String, Object> cache = new ConcurrentHashMap<>();
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Cacheable cacheable = method.getAnnotation(Cacheable.class);
if (cacheable == null) {
return method.invoke(target, args);
}
String cacheKey = buildCacheKey(method, args, cacheable.keyPrefix());
if (cache.containsKey(cacheKey)) {
return cache.get(cacheKey);
}
Object result = method.invoke(target, args);
cache.put(cacheKey, result);
// 简单实现TTL,实际项目会用Redis等
if (cacheable.ttl() > 0) {
new Timer().schedule(new TimerTask() {
@Override
public void run() {
cache.remove(cacheKey);
}
}, cacheable.ttl() * 1000L);
}
return result;
}
private String buildCacheKey(Method method, Object[] args, String prefix) {
// 构建缓存键逻辑
}
}
对于需要处理异步任务的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Async {
String executor() default "default";
}
public class AsyncProcessor {
private final Map<String, ExecutorService> executors = new HashMap<>();
public AsyncProcessor() {
executors.put("default", Executors.newCachedThreadPool());
executors.put("io", Executors.newFixedThreadPool(10));
executors.put("cpu", Executors.newWorkStealingPool());
}
public Object process(Object target, Method method, Object[] args) {
Async async = method.getAnnotation(Async.class);
if (async == null) {
try {
return method.invoke(target, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
ExecutorService executor = executors.get(async.executor());
if (executor == null) {
throw new IllegalArgumentException("Unknown executor: " + async.executor());
}
Future<?> future = executor.submit(() -> {
try {
return method.invoke(target, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
return new AsyncResult(future);
}
}
在配置管理方面,可以定义配置注入注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Value {
String key();
String defaultValue() default "";
}
public class ConfigInjector {
private final Properties config;
public ConfigInjector(Properties config) {
this.config = config;
}
public void inject(Object target) throws IllegalAccessException {
for (Field field : target.getClass().getDeclaredFields()) {
Value value = field.getAnnotation(Value.class);
if (value == null) continue;
String configValue = config.getProperty(value.key(), value.defaultValue());
if (configValue == null) continue;
field.setAccessible(true);
Class<?> type = field.getType();
if (type == String.class) {
field.set(target, configValue);
} else if (type == int.class || type == Integer.class) {
field.set(target, Integer.parseInt(configValue));
} else if (type == boolean.class || type == Boolean.class) {
field.set(target, Boolean.parseBoolean(configValue));
}
// 其他类型处理...
}
}
}
对于需要处理事件监听的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EventListener {
Class<? extends Event> eventType();
}
public class EventBus {
private final Map<Class<?>, List<Method>> listeners = new HashMap<>();
public void register(Object listener) {
for (Method method : listener.getClass().getMethods()) {
EventListener annotation = method.getAnnotation(EventListener.class);
if (annotation == null) continue;
Class<?> eventType = annotation.eventType();
listeners.computeIfAbsent(eventType, k -> new ArrayList<>()).add(method);
}
}
public void post(Event event) {
List<Method> methods = listeners.get(event.getClass());
if (methods == null) return;
for (Method method : methods) {
try {
method.invoke(method.getDeclaringClass().newInstance(), event);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
在权限控制方面,可以定义权限注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresRole {
String[] value();
}
public class SecurityInterceptor {
private final Set<String> userRoles;
public SecurityInterceptor(Set<String> userRoles) {
this.userRoles = userRoles;
}
public Object secureInvoke(Object target, Method method, Object[] args) throws Throwable {
RequiresRole requiresRole = method.getAnnotation(RequiresRole.class);
if (requiresRole == null) {
return method.invoke(target, args);
}
for (String requiredRole : requiresRole.value()) {
if (userRoles.contains(requiredRole)) {
return method.invoke(target, args);
}
}
throw new SecurityException("Access denied");
}
}
对于需要处理重试逻辑的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retryable {
int maxAttempts() default 3;
Class<? extends Throwable>[] retryOn() default {Exception.class};
long delay() default 1000;
}
public class RetryProcessor {
public Object process(Object target, Method method, Object[] args) throws Throwable {
Retryable retryable = method.getAnnotation(Retryable.class);
if (retryable == null) {
return method.invoke(target, args);
}
int attempts = 0;
Throwable lastError;
do {
try {
return method.invoke(target, args);
} catch (InvocationTargetException e) {
lastError = e.getCause();
if (!shouldRetry(retryable, lastError)) {
throw lastError;
}
if (attempts < retryable.maxAttempts() - 1) {
Thread.sleep(retryable.delay());
}
}
attempts++;
} while (attempts < retryable.maxAttempts());
throw lastError;
}
private boolean shouldRetry(Retryable retryable, Throwable error) {
for (Class<? extends Throwable> retryOn : retryable.retryOn()) {
if (retryOn.isInstance(error)) {
return true;
}
}
return false;
}
}
在事务管理方面,可以定义事务注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Transactional {
int timeout() default 30; // seconds
boolean readOnly() default false;
}
public class TransactionManager {
public Object executeInTransaction(Object target, Method method, Object[] args) throws Throwable {
Transactional transactional = method.getAnnotation(Transactional.class);
if (transactional == null) {
return method.invoke(target, args);
}
Connection connection = null;
try {
connection = getConnection();
connection.setAutoCommit(false);
connection.setReadOnly(transactional.readOnly());
Object result = method.invoke(target, args);
connection.commit();
return result;
} catch (Throwable e) {
if (connection != null) {
connection.rollback();
}
throw e;
} finally {
if (connection != null) {
connection.close();
}
}
}
private Connection getConnection() {
// 获取数据库连接
}
}
对于需要处理定时任务的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Scheduled {
long fixedRate() default -1; // milliseconds
String cron() default "";
}
public class TaskScheduler {
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(4);
public void schedule(Object target) {
for (Method method : target.getClass().getMethods()) {
Scheduled scheduled = method.getAnnotation(Scheduled.class);
if (scheduled == null) continue;
if (scheduled.fixedRate() > 0) {
executor.scheduleAtFixedRate(() -> {
try {
method.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
}, 0, scheduled.fixedRate(), TimeUnit.MILLISECONDS);
} else if (!scheduled.cron().isEmpty()) {
// 解析cron表达式并调度
}
}
}
}
在日志处理方面,可以定义日志注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Loggable {
Level value() default Level.INFO;
boolean logParams() default true;
boolean logResult() default false;
}
public class LoggingAspect {
private static final Logger logger = Logger.getLogger(LoggingAspect.class.getName());
public Object logMethodCall(Object target, Method method, Object[] args) throws Throwable {
Loggable loggable = method.getAnnotation(Loggable.class);
if (loggable == null) {
return method.invoke(target, args);
}
String methodName = method.getName();
if (loggable.logParams()) {
logger.log(loggable.value(),
"Entering " + methodName + " with args: " + Arrays.toString(args));
} else {
logger.log(loggable.value(), "Entering " + methodName);
}
Object result = method.invoke(target, args);
if (loggable.logResult()) {
logger.log(loggable.value(),
"Exiting " + methodName + " with result: " + result);
} else {
logger.log(loggable.value(), "Exiting " + methodName);
}
return result;
}
}
在性能监控方面,可以定义监控注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Monitored {
String name() default "";
}
public class PerformanceMonitor {
private final Map<String, Stats> statsMap = new ConcurrentHashMap<>();
public Object monitor(Object target, Method method, Object[] args) throws Throwable {
Monitored monitored = method.getAnnotation(Monitored.class);
if (monitored == null) {
return method.invoke(target, args);
}
String metricName = monitored.name().isEmpty() ?
method.getDeclaringClass().getSimpleName() + "." + method.getName() :
monitored.name();
long start = System.nanoTime();
try {
Object result = method.invoke(target, args);
recordSuccess(metricName, start);
return result;
} catch (Exception e) {
recordFailure(metricName, start);
throw e;
}
}
private void recordSuccess(String name, long startTime) {
Stats stats = statsMap.computeIfAbsent(name, k -> new Stats());
long duration = System.nanoTime() - startTime;
stats.recordSuccess(duration);
}
private void recordFailure(String name, long startTime) {
Stats stats = statsMap.computeIfAbsent(name, k -> new Stats());
long duration = System.nanoTime() - startTime;
stats.recordFailure(duration);
}
private static class Stats {
// 统计信息实现
}
}
对于需要处理验证的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ValidEmail {
String message() default "Invalid email format";
}
public class Validator {
private static final Pattern EMAIL_PATTERN =
Pattern.compile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE);
public static void validate(Object obj) throws IllegalAccessException, ValidationException {
for (Field field : obj.getClass().getDeclaredFields()) {
ValidEmail validEmail = field.getAnnotation(ValidEmail.class);
if (validEmail == null) continue;
field.setAccessible(true);
Object value = field.get(obj);
if (value == null) continue;
if (!(value instanceof String)) {
throw new ValidationException(field.getName() + " must be a string");
}
String email = (String) value;
if (!EMAIL_PATTERN.matcher(email).matches()) {
throw new ValidationException(validEmail.message());
}
}
}
}
在RPC框架中,可以定义远程服务注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RemoteService {
String serviceName();
}
public class RpcProxy implements InvocationHandler {
private final String serviceUrl;
private final String serviceName;
public static <T> T createProxy(Class<T> interfaceType, String serviceUrl) {
RemoteService remoteService = interfaceType.getAnnotation(RemoteService.class);
if (remoteService == null) {
throw new IllegalArgumentException("Interface must be annotated with @RemoteService");
}
return (T) Proxy.newProxyInstance(
interfaceType.getClassLoader(),
new Class<?>[] { interfaceType },
new RpcProxy(serviceUrl, remoteService.serviceName())
);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 构建RPC请求并发送
RpcRequest request = new RpcRequest();
request.setServiceName(serviceName);
request.setMethodName(method.getName());
request.setParameterTypes(method.getParameterTypes());
request.setParameters(args);
// 发送请求并获取响应
RpcResponse response = sendRequest(serviceUrl, request);
if (response.getError() != null) {
throw response.getError();
}
return response.getResult();
}
}
对于需要处理国际化(i18n)的场景:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface I18n {
String key();
}
public class I18nProcessor {
private final ResourceBundle bundle;
public I18nProcessor(Locale locale) {
this.bundle = ResourceBundle.getBundle("messages", locale);
}
public void process(Object target) throws IllegalAccessException {
for (Field field : target.getClass().getDeclaredFields()) {
I18n i18n = field.getAnnotation(I18n.class);
if (i18n == null) continue;
if (field.getType() != String.class) {
throw new IllegalArgumentException("@I18n can only be applied to String fields");
}
field.setAccessible(true);
field.set(target, bundle.getString(i18n.key()));
}
}
}
在测试数据生成方面,可以定义数据生成注解:
java复制@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface RandomValue {
int min() default 0;
int max() default 100;
boolean unique() default false;
}
public class TestDataGenerator {
private final Random random = new Random();
private final Set<Integer> usedIntegers = new HashSet<>();
public void generate(Object testData) throws IllegalAccessException {
for (Field field : testData.getClass().getDeclaredFields()) {
RandomValue randomValue = field.getAnnotation(RandomValue.class);
if (randomValue == null) continue;
field.setAccessible(true);
Class<?> type = field.getType();
if (type == int.class || type == Integer.class) {
int value;
do {
value = randomValue.min() + random.nextInt(random
