You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Javalin+Guice项目中实现自定义@Regex注解自动生效方案咨询

实现方案:利用Guice AOP自动处理@Regex注解

Guice的AOP(面向切面编程)可以自动拦截带有自定义注解的方法/字段,无需手动调用处理器方法。下面是完整的实现示例:

1. 定义@Regex注解

设置正确的保留策略与目标类型,确保Guice能在运行时识别并拦截:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.FIELD}) // 支持作用在方法或字段上
public @interface Regex {
    String pattern(); // 匹配正则表达式
    String replacement(); // 替换内容
}

2. 实现Guice方法拦截器

拦截带有@Regex注解的方法,自动处理返回值的正则替换:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class RegexInterceptor implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 先执行原方法获取返回值
        Object result = invocation.proceed();
        
        // 仅处理字符串类型返回值,且方法带有@Regex注解的情况
        if (result instanceof String) {
            Regex regexAnnotation = invocation.getMethod().getAnnotation(Regex.class);
            if (regexAnnotation != null) {
                return ((String) result).replaceAll(regexAnnotation.pattern(), regexAnnotation.replacement());
            }
        }
        return result;
    }
}

3. 配置Guice模块

绑定拦截器与@Regex注解,指定拦截规则:

import com.google.inject.AbstractModule;
import com.google.inject.matcher.Matchers;

public class AppModule extends AbstractModule {
    @Override
    protected void configure() {
        // 拦截所有带有@Regex注解的方法
        bindInterceptor(Matchers.any(), Matchers.annotatedWith(Regex.class), new RegexInterceptor());
        
        // 绑定项目其他服务/实现类,示例:
        // bind(UserService.class).to(UserServiceImpl.class);
    }
}

4. 整合Javalin与Guice

让Javalin通过Guice管理Bean,确保拦截器生效:

import com.google.inject.Guice;
import com.google.inject.Injector;
import io.javalin.Javalin;

public class MainApp {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new AppModule());
        
        Javalin app = Javalin.create(config -> {
            // 配置Javalin使用Guice进行依赖注入
            config.dependencyInjector(injector::getInstance);
        });
        
        // 注册由Guice管理的控制器
        app.get("/test", injector.getInstance(TestController.class)::handleTest);
        
        app.start(8080);
    }
}

5. 使用@Regex注解的示例控制器

直接在方法上标注注解,无需手动调用处理器:

import io.javalin.http.Context;

public class TestController {

    @Regex(pattern = "\\d+", replacement = "***")
    public String handleTest(Context ctx) {
        // 返回的字符串会被自动替换数字为***
        return "我的手机号是13812345678";
    }
}

访问/test时,返回内容自动变为我的手机号是***。

扩展:处理字段自动替换

如果需要对类字段自动处理(如身份证号脱敏),可以实现字段监听处理器:

import com.google.inject.TypeLiteral;
import com.google.inject.spi.TypeEncounter;
import com.google.inject.spi.TypeListener;
import com.google.inject.spi.MembersInjector;
import java.lang.reflect.Field;

// 字段监听类
public class RegexFieldListener implements TypeListener {
    @Override
    public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
        for (Field field : typeLiteral.getRawType().getDeclaredFields()) {
            if (field.isAnnotationPresent(Regex.class)) {
                Regex regex = field.getAnnotation(Regex.class);
                typeEncounter.register(new RegexFieldInjector<>(field, regex));
            }
        }
    }
}

// 字段注入处理器
class RegexFieldInjector<T> implements MembersInjector<T> {
    private final Field field;
    private final Regex regex;

    public RegexFieldInjector(Field field, Regex regex) {
        this.field = field;
        this.regex = regex;
        field.setAccessible(true);
    }

    @Override
    public void injectMembers(T instance) {
        try {
            Object value = field.get(instance);
            if (value instanceof String) {
                String processed = ((String) value).replaceAll(regex.pattern(), regex.replacement());
                field.set(instance, processed);
            }
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}

在Guice模块中注册字段监听:

@Override
protected void configure() {
    // ... 原有拦截器绑定
    bindListener(Matchers.any(), new RegexFieldListener());
}

之后实例化带有@Regex注解字段的类时,字段值会自动被处理。

内容的提问来源于stack exchange,提问作者Ger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:43:35