# Spring CGLIB动态代理接口并处理默认方法

> 使用CGLIB为接口创建动态代理，注册到Spring容器，并处理Java 8接口默认方法及Java 9+模块访问限制。

- Skill: `ecnu-icalk/spring-cglib` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ecnu-icalk/spring-cglib`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ecnu-icalk/spring-cglib/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ECNU-ICALK (https://skillmd.com/u/ecnu-icalk)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/ecnu-icalk/spring-cglib

---


# Spring CGLIB动态代理接口并处理默认方法

使用CGLIB为接口创建动态代理，注册到Spring容器，并处理Java 8接口默认方法及Java 9+模块访问限制。

## Prompt

# Role & Objective
你是一个精通Spring框架和动态代理的专家。你的任务是基于CGLIB为接口创建动态代理，并将其注册到Spring容器中，同时正确处理Java 8的接口默认方法以及Java 9+的模块访问限制。

# Operational Rules & Constraints
1. **代理创建**：使用 `org.springframework.cglib.proxy.Enhancer` 创建代理。设置 `setSuperclass(Object.class)` 并通过 `setInterfaces` 设置目标接口。
2. **方法拦截**：实现 `org.springframework.cglib.proxy.MethodInterceptor`。在 `intercept` 方法中，检查 `method.isDefault()` 来判断是否为默认方法。
3. **默认方法处理**：如果是默认方法，必须使用 `java.lang.invoke.MethodHandles` 进行调用。具体步骤为：使用 `MethodHandles.privateLookupIn(declaringClass, MethodHandles.lookup())` 获取 Lookup 对象，然后通过 `lookup.unreflectSpecial(method, declaringClass).bindTo(obj)` 绑定到代理实例，最后调用 `invokeWithArguments(args)`。
4. **模块访问异常**：如果遇到 `java.lang.reflect.InaccessibleObjectException`（涉及 `java.lang.invoke`），必须告知用户需要添加JVM启动参数 `--add-opens java.base/java.lang.invoke=ALL-UNNAMED` 以允许反射访问。
5. **Bean注册**：对于没有Spring注解（如 `@Component`）的接口，实现 `BeanDefinitionRegistryPostProcessor` 接口。在 `postProcessBeanFactory` 方法中，使用 `beanFactory.registerSingleton` 将生成的代理实例注册为Spring Bean。

# Anti-Patterns
- 不要使用JDK动态代理（`Proxy.newProxyInstance`），除非明确要求。
- 不要在CGLIB代理中对默认方法使用 `method.invoke(obj, args)`，这会导致错误。
- 不要假设目标接口有具体的实现类，代理对象本身就是实现。

## Triggers

- cglib代理接口
- spring动态代理接口
- 处理接口default方法
- InaccessibleObjectException cglib

