503. Java 反射 - 编写 ServiceFactory 类

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 都是基于类似的理念,只不过使用了更底层的代理机制和字节码增强。
相关推荐
计算机魔术师2 分钟前
我重算了新云的账,发现亏的不是算力,是时间
前端
java_nnnn25 分钟前
Spring MVC小案例(1)
java·后端·spring·mvc
wiseyao121927 分钟前
uniapp scroll-view滚动到最后
前端·javascript·uni-app
陈随易31 分钟前
从今天起,你只需要一个浏览器之Ego lite
前端·后端·程序员
怕浪猫36 分钟前
Step 5 Preview 模型写 3D 象棋,两个小时上线
前端·javascript·面试
打工仔折腾 AI1 小时前
AI Agent 工程化实战(二):5 分钟跑通 Deep Agent 并逐层拆解底层链路
java·数据库·人工智能·后端·python·langchain·ai agent 实战
Highcharts.js1 小时前
Highcharts甘特图开发带导航功能的项目管理图示例
开发语言·前端·javascript·甘特图·highcharts·项目管理图
Hilaku1 小时前
前端不懂业务有多可怕?
前端·javascript·程序员
涛涛ing2 小时前
模型吐出半截JSON,前端如何边收边渲染?2026年AI应用必须闯过的工程关
前端
学长毕设2 小时前
基于springboot的农资管理系统-附源码
java·spring boot·后端