501. Java 反射 - 使用注解与接口设计拦截器
2026/8/22 22:22:40 网站建设 项目流程

文章目录

  • 501. Java 反射 - 使用注解与接口设计拦截器
    • 1. 为什么要定义拦截器接口?
      • 接口定义
    • 2. 定义拦截注解
    • 3. 编写业务服务类
    • 4. 编写一个拦截器实现类
    • 5. 设计一个 ServiceFactory 来统一调用
    • 6. 测试拦截功能
    • 7. 总结

501. Java 反射 - 使用注解与接口设计拦截器

1. 为什么要定义拦截器接口?

我们希望在调用某个方法前后插入自定义逻辑(如日志、安全校验、数据转换等)。为了让这个机制通用化,我们定义一个拦截器接口,所有拦截器都必须实现它。

接口定义

publicinterfaceInterceptor<T,R>{Rintercept(TinterceptedObject,Methodmethod,Object...arguments);}
  • T interceptedObject→ 被拦截的对象(例如一个 Service 实例)。
  • Method method→ 被拦截的方法。
  • Object... arguments→ 方法调用时传入的参数。
  • R→ 方法的返回值类型。

👉 使用泛型保证了接口的灵活性,既能拦截返回String的方法,也能拦截返回User的方法。


2. 定义拦截注解

我们需要一个注解来标记哪些方法需要被拦截,以及指定使用哪个拦截器。

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceIntercept{Class<?extendsInterceptor<?,?>>value();}
  • @Target(ElementType.METHOD)→ 注解只能放在方法上。
  • @Retention(RetentionPolicy.RUNTIME)→ 在运行时依然保留,供反射使用。
  • value()→ 指定具体的拦截器类。

3. 编写业务服务类

publicclassSomeInterceptedService{@Intercept(MessageInterceptor.class)publicStringmessage(Stringinput){returninput.toUpperCase();}}
  • 方法message()@Intercept标记。
  • 拦截器类MessageInterceptor将会替代message()的直接执行。

4. 编写一个拦截器实现类

我们来实现一个简单的拦截器,它会在调用message()前后打印日志。

publicclassMessageInterceptorimplementsInterceptor<SomeInterceptedService,String>{@OverridepublicStringintercept(SomeInterceptedServiceservice,Methodmethod,Object...arguments){System.out.println("👉 Before invoking "+method.getName());try{// 真实调用被拦截的方法Stringresult=(String)method.invoke(service,arguments);System.out.println("👉 After invoking, result = "+result);returnresult;}catch(Exceptione){thrownewRuntimeException("Interceptor caught exception",e);}}}

运行逻辑:

  • 在方法执行前打印日志。
  • 执行目标方法 (method.invoke)。
  • 在方法执行后打印返回值。

5. 设计一个 ServiceFactory 来统一调用

我们需要一个工厂类ServiceFactory来读取注解并执行拦截逻辑。

publicclassServiceFactory{@SuppressWarnings("unchecked")publicstatic<T>Objectinvoke(Class<T>serviceClass,StringmethodName,Object...args)throwsException{Tservice=serviceClass.getDeclaredConstructor().newInstance();Methodmethod=serviceClass.getMethod(methodName,String.class);if(method.isAnnotationPresent(Intercept.class)){InterceptinterceptAnnotation=method.getAnnotation(Intercept.class);Class<?extendsInterceptor<?,?>>interceptorClass=interceptAnnotation.value();Interceptor<T,?>interceptor=(Interceptor<T,?>)interceptorClass.getDeclaredConstructor().newInstance();returninterceptor.intercept(service,method,args);}else{returnmethod.invoke(service,args);}}}

👉 流程:

  1. 通过反射创建服务实例。
  2. 找到方法并检查是否有@Intercept
  3. 如果有,执行对应的拦截器逻辑。
  4. 如果没有,直接调用原始方法。

6. 测试拦截功能

publicclassMain{publicstaticvoidmain(String[]args)throwsException{Stringoutput=(String)ServiceFactory.invoke(SomeInterceptedService.class,"message","Hello");System.out.println("Final output = "+output);}}

运行结果:

👉Beforeinvoking message 👉Afterinvoking,result=HELLOFinaloutput=HELLO

7. 总结

  • Interceptor<T, R>定义了拦截器的通用接口。
  • @Intercept注解用来声明哪些方法需要拦截,以及由哪个拦截器处理。
  • 业务类通过注解与拦截器解耦,不需要手动调用拦截器。
  • ServiceFactory承担了框架的角色,把注解与拦截器绑定在一起。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询