
文章目录501. Java 反射 - 使用注解与接口设计拦截器1. 为什么要定义拦截器接口接口定义2. 定义拦截注解3. 编写业务服务类4. 编写一个拦截器实现类5. 设计一个 ServiceFactory 来统一调用6. 测试拦截功能7. 总结501. Java 反射 - 使用注解与接口设计拦截器1. 为什么要定义拦截器接口我们希望在调用某个方法前后插入自定义逻辑如日志、安全校验、数据转换等。为了让这个机制通用化我们定义一个拦截器接口所有拦截器都必须实现它。接口定义publicinterfaceInterceptorT,R{Rintercept(TinterceptedObject,Methodmethod,Object...arguments);}T interceptedObject→ 被拦截的对象例如一个 Service 实例。Method method→ 被拦截的方法。Object... arguments→ 方法调用时传入的参数。R→ 方法的返回值类型。 使用泛型保证了接口的灵活性既能拦截返回String的方法也能拦截返回User的方法。2. 定义拦截注解我们需要一个注解来标记哪些方法需要被拦截以及指定使用哪个拦截器。Target(ElementType.METHOD)Retention(RetentionPolicy.RUNTIME)publicinterfaceIntercept{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()前后打印日志。publicclassMessageInterceptorimplementsInterceptorSomeInterceptedService,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)publicstaticTObjectinvoke(ClassTserviceClass,StringmethodName,Object...args)throwsException{TserviceserviceClass.getDeclaredConstructor().newInstance();MethodmethodserviceClass.getMethod(methodName,String.class);if(method.isAnnotationPresent(Intercept.class)){InterceptinterceptAnnotationmethod.getAnnotation(Intercept.class);Class?extendsInterceptor?,?interceptorClassinterceptAnnotation.value();InterceptorT,?interceptor(InterceptorT,?)interceptorClass.getDeclaredConstructor().newInstance();returninterceptor.intercept(service,method,args);}else{returnmethod.invoke(service,args);}}} 流程通过反射创建服务实例。找到方法并检查是否有Intercept。如果有执行对应的拦截器逻辑。如果没有直接调用原始方法。6. 测试拦截功能publicclassMain{publicstaticvoidmain(String[]args)throwsException{Stringoutput(String)ServiceFactory.invoke(SomeInterceptedService.class,message,Hello);System.out.println(Final output output);}}运行结果Beforeinvoking message Afterinvoking,resultHELLOFinaloutputHELLO7. 总结InterceptorT, R定义了拦截器的通用接口。Intercept注解用来声明哪些方法需要拦截以及由哪个拦截器处理。业务类通过注解与拦截器解耦不需要手动调用拦截器。ServiceFactory承担了框架的角色把注解与拦截器绑定在一起。