java中通过自定义@ipwhitelist注解结合spring aop实现ip黑白名单动态拦截,支持运行时从redis或配置中心加载白名单、模式切换(white/black)、真实ip提取及管理接口刷新,无需重启应用。

<p>Java中通过自定义注解实现IP黑白名单动态拦截,核心是结合Spring AOP(面向切面)+ 自定义注解 + IP校验逻辑,无需硬编码、支持运行时配置(如从数据库或配置中心加载白名单),灵活可扩展。</p>
<h3>定义 @IPWhiteList 注解</h3>
<p>声明一个运行时保留、可用于方法上的自定义注解,支持指定拦截模式(白名单/黑名单)、是否启用、提示消息等:</p>
<p><font color="gray">@Target(ElementType.METHOD)<br>@Retention(RetentionPolicy.RUNTIME)<br>@Documented<br>public @interface IPWhiteList {<br> String[] value() default {}; // 默认白名单IP数组(兜底)<br> boolean enable() default true; // 是否启用拦截<br> Mode mode() default Mode.WHITE; // WHITE 或 BLACK<br> String message() default "Access denied";<br><br> enum Mode { WHITE, BLACK }<br>}</font></p>
<h3>编写AOP切面拦截逻辑</h3>
<p>使用@Around环绕通知,在方法执行前获取客户端真实IP,并根据注解配置决定是否放行:</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill7957" title="js2java"><img
src="https://img.php.cn/upload/skill/000/000/081/179178140274370.jpg" alt="js2java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill7957" title="js2java" class="overflowclass">js2java</a>
<p class="overflowclass">JavaScript 到 Java 全栈翻译助手,专为前端开发者学习 Java 或快速实现后端业务逻辑而设计。当用户提到以下场景时必须使用此技能: - "帮我把这段 JS 代码转成 Java" - "用 Java 怎么写这个逻辑" - "我习惯用 JS 写,想翻译成 Java" - "教我 Java,我要写后端接...</p>
</div>
<a rel="nofollow" href="/xiazai/skill7957" title="js2java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
- 从请求头(X-Forwarded-For、X-Real-IP)或request.getRemoteAddr()提取真实IP
- 读取注解的mode和value,再结合动态白名单(例如从Redis或数据库查出最新列表)
- 白名单模式:IP不在列表中 → 拒绝;黑名单模式:IP在列表中 → 拒绝
- 抛出自定义异常(如AccessDeniedException)或直接返回HTTP 403响应
支持动态白名单刷新
避免重启应用更新IP列表,推荐以下方式:
- 将白名单存入Redis,设置过期时间,AOP切面每次拦截时调用Redis查询(建议加本地缓存+定时刷新,减少延迟)
- 提供管理接口(如POST /admin/ip/whitelist),接收IP列表并同步更新Redis
- 监听配置中心(Nacos/Apollo)变更事件,自动刷新内存缓存中的IP集合
在Controller方法上使用
只需在需要保护的方法上添加注解,支持表达式或默认值:
@GetMapping("/api/data")
@IPWhiteList(enable = true, mode = IPWhiteList.Mode.WHITE, message = "IP not authorized")
public Result getData() { ... }
若注解未指定value,则完全依赖动态加载的白名单;也可写死少量测试IP用于开发环境快速验证。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










