503. Java 反射 - 编写 ServiceFactory 类

文章目录

  • [503. Java 反射 - 编写 ServiceFactory 类](#503. Java 反射 - 编写 ServiceFactory 类)
    • [1. 设计目标](#1. 设计目标)
    • [2. 核心实现代码](#2. 核心实现代码)
    • [3. 示例说明](#3. 示例说明)
      • [(1) 带拦截器的服务](#(1) 带拦截器的服务)
      • [(2) 没有拦截器的服务](#(2) 没有拦截器的服务)
      • [(3) 测试调用](#(3) 测试调用)
      • [(4) 运行结果](#(4) 运行结果)
    • 4.总结

503. Java 反射 - 编写 ServiceFactory 类

1. 设计目标

ServiceFactory 的职责是 统一拦截服务方法的调用

  • 它接收:服务类、方法名、方法参数
  • 自动创建服务实例。
  • 找到目标方法,并判断是否带有 @Intercept 注解。
  • 如果有注解 → 使用对应的拦截器来执行方法逻辑。
  • 如果没有注解 → 直接调用方法。

这样我们就实现了一个简化版的 拦截器机制


2. 核心实现代码

java 复制代码
public class ServiceFactory {
    public static <T, R> R invoke(
            Class<? extends T> serviceClass, String methodName, Object... arguments) {
        try {
            // ✅ 1. 创建服务实例(要求必须有无参构造器)
            T service = serviceClass.getConstructor().newInstance();

            // ✅ 2. 确定参数类型数组,用于定位目标方法
            Class<?>[] parameterClasses =
                    Arrays.stream(arguments).map(Object::getClass).toArray(Class<?>[]::new);
            Method method = serviceClass.getDeclaredMethod(methodName, parameterClasses);

            // ✅ 3. 判断方法上是否存在 @Intercept 注解
            if (method.isAnnotationPresent(Intercept.class)) {
                Intercept intercept = method.getDeclaredAnnotation(Intercept.class);

                // 获取拦截器类,并实例化
                Class<? extends Interceptor<T, R>> interceptorClass =
                        (Class<? extends Interceptor<T, R>>) intercept.value();
                Interceptor<T, R> interceptor = interceptorClass.getConstructor().newInstance();

                // ✅ 4. 使用拦截器执行方法
                return interceptor.intercept(service, method, arguments);
            } else {
                // ✅ 5. 没有注解 → 直接反射调用
                return (R) method.invoke(service, arguments);
            }
        } catch (InstantiationException | IllegalAccessException |
                 InvocationTargetException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
    }
}

3. 示例说明

(1) 带拦截器的服务

java 复制代码
public class SomeInterceptedService {
    @Intercept(MessageInterceptor.class)
    public String message(String input) {
        return input.toUpperCase();
    }
}

(2) 没有拦截器的服务

java 复制代码
public class SomeNonInterceptedService {
    public String message(String input) {
        return input.toUpperCase();
    }
}

(3) 测试调用

java 复制代码
public class Main {
    public static void main(String[] args) {
        String interceptedOutput =
                ServiceFactory.invoke(SomeInterceptedService.class, "message", "Hello");
        System.out.println("Intercepted output = " + interceptedOutput);

        String nonInterceptedOutput =
                ServiceFactory.invoke(SomeNonInterceptedService.class, "message", "Hello");
        System.out.println("Non intercepted output = " + nonInterceptedOutput);
    }
}

(4) 运行结果

java 复制代码
Intercepted output = HELLO [was intercepted]
Non intercepted output = HELLO

4.总结

  • 统一入口 :不管有没有拦截器,ServiceFactory.invoke() 都能完成方法调用。
  • 灵活扩展:不同方法可以使用不同的拦截器(比如日志拦截器、权限拦截器、缓存拦截器)。
  • 类型不安全:由于反射和强制类型转换,编译期无法保证安全性 → 运行时可能抛出异常。
  • 对比实际框架:Spring AOP、Jakarta EE Interceptor 都是基于类似的理念,只不过使用了更底层的代理机制和字节码增强。
相关推荐
君顾11 分钟前
西安 24 小时自助健身房系统开发实战指南
java·开发语言·健身房
用户094248568032 分钟前
第9章:OpenJDK堆分代与 Serial/Parallel GC 基础
java·jvm
Wang's Blog11 分钟前
Java框架快速入门: Spring Security+OAuth2之RBAC与角色分层实践
java·网络·spring
caoerzhong23 分钟前
JeeWMS 开源仓库管理系统多租户架构解析:一套 Java WMS 如何同时服务多个货主与多个仓库
java·架构·开源·vue
抓不住时间的沙23 分钟前
Butterfly主题 5.7 导航栏添加相册同时设置相册入口密码
css·python·node.js
sunshine22 girl29 分钟前
Java学习四 面向对象原理
java
干到60岁退休的码农31 分钟前
15.创建获取用户接口与JWT认证器
java·spring boot·mybatis
风合星语35 分钟前
2026 机器人工程实例(五):让 Allegro Hand 在 MuJoCo 中完成接触抓取——抓取状态机、稳定抬升与受控释放
c++·python·机器人·仿真
小羊没烦恼!36 分钟前
Memory 记忆设计讨论:Agent Memory 的数据模型可以怎么设计
java·开发语言·前端·c++·c#
SL_staff44 分钟前
战略落地的最后一公里:从目标到个人日历的自动化链路实现
java·github·全栈