500. Java 反射 - 使用注解创建拦截器

500. Java 反射 - 使用注解创建拦截器

1. 什么是拦截器 (Interceptor)?

拦截器是一种横切关注点处理机制,在很多框架中非常常见,比如 Java EE、Jakarta EE、Spring AOP 等。

核心思想:

  • 业务方法本身只关心业务逻辑。
  • 拦截器在业务方法执行前后介入,完成其他功能(日志、校验、安全、事务、异常处理等)。
  • 通过注解声明要拦截的方法,使得代码简洁、解耦。

👉 可以把拦截器想象成“门卫”:

  • 方法就是门后的人,
  • 拦截器决定是否允许进门、是否需要额外检查,还可以在出去时再加一些操作。

2. 我们要实现的目标

我们设计一个简单的机制:

  1. 在业务方法上打一个注解 @Intercept
  2. 注解中指定一个拦截器类
  3. 当调用业务方法时,实际执行的是拦截器里的逻辑,而不是直接运行业务方法。

3. 定义拦截器注解

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Intercept {
    Class<? extends MethodInterceptor> value();
}

👉 这里我们定义了一个 @Intercept 注解:

  • @Target(ElementType.METHOD):只能用在方法上。
  • value():用来指定一个拦截器类,必须实现我们定义的 MethodInterceptor 接口。

4. 定义拦截器接口

public interface MethodInterceptor {
    Object invoke(Method method, Object target, Object[] args) throws Exception;
}

说明:

  • method → 被拦截的方法对象
  • target → 被调用的目标对象
  • args → 调用方法时传入的参数

5. 编写一个具体拦截器

比如我们要做一个简单的 日志拦截器

public class LoggingInterceptor implements MethodInterceptor {
    @Override
    public Object invoke(Method method, Object target, Object[] args) throws Exception {
        System.out.println("👉 调用方法: " + method.getName());
        System.out.println("👉 参数: " + Arrays.toString(args));

        Object result = method.invoke(target, args);

        System.out.println("👉 返回值: " + result);
        return result;
    }
}

6. 在业务类中使用拦截器

public class UserService {

    @Intercept(LoggingInterceptor.class)
    public String sayHello(String name) {
        return "Hello, " + name;
    }
}

7. 执行拦截逻辑

我们用反射来检查方法是否带有 @Intercept 注解,如果有,则执行对应的拦截器。

public class InterceptorRunner {

    public static void run(Object target, String methodName, Object... args) throws Exception {
        Method method = target.getClass().getMethod(methodName, String.class);

        if (method.isAnnotationPresent(Intercept.class)) {
            Intercept annotation = method.getAnnotation(Intercept.class);
            MethodInterceptor interceptor = annotation.value().getDeclaredConstructor().newInstance();
            interceptor.invoke(method, target, args);
        } else {
            method.invoke(target, args);
        }
    }

    public static void main(String[] args) throws Exception {
        UserService service = new UserService();
        run(service, "sayHello", "Alice");
    }
}

8. 运行结果

👉 调用方法: sayHello
👉 参数: [Alice]
👉 返回值: Hello, Alice

9. 总结

  • 拦截器让我们可以在方法调用前后执行额外逻辑。
  • 注解 + 反射提供了一种轻量级的方式来实现类似 AOP 的功能。
  • 在企业框架里,这种思想被广泛用于:
    • 日志打印
    • 参数校验
    • 安全检查
    • 事务管理
    • 异常统一处理
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容