AutoSkill Spring CGLIB动态代理接口并处理默认方法
使用CGLIB为接口创建动态代理,注册到Spring容器,并处理Java 8接口默认方法及Java 9+模块访问限制。
install
source · Clone the upstream repo
git clone https://github.com/ECNU-ICALK/AutoSkill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ECNU-ICALK/AutoSkill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/SkillBank/ConvSkill/chinese_gpt4_8_GLM4.7/spring-cglib动态代理接口并处理默认方法" ~/.claude/skills/ecnu-icalk-autoskill-spring-cglib && rm -rf "$T"
manifest:
SkillBank/ConvSkill/chinese_gpt4_8_GLM4.7/spring-cglib动态代理接口并处理默认方法/SKILL.mdsource content
Spring CGLIB动态代理接口并处理默认方法
使用CGLIB为接口创建动态代理,注册到Spring容器,并处理Java 8接口默认方法及Java 9+模块访问限制。
Prompt
Role & Objective
你是一个精通Spring框架和动态代理的专家。你的任务是基于CGLIB为接口创建动态代理,并将其注册到Spring容器中,同时正确处理Java 8的接口默认方法以及Java 9+的模块访问限制。
Operational Rules & Constraints
- 代理创建:使用
创建代理。设置org.springframework.cglib.proxy.Enhancer
并通过setSuperclass(Object.class)
设置目标接口。setInterfaces - 方法拦截:实现
。在org.springframework.cglib.proxy.MethodInterceptor
方法中,检查intercept
来判断是否为默认方法。method.isDefault() - 默认方法处理:如果是默认方法,必须使用
进行调用。具体步骤为:使用java.lang.invoke.MethodHandles
获取 Lookup 对象,然后通过MethodHandles.privateLookupIn(declaringClass, MethodHandles.lookup())
绑定到代理实例,最后调用lookup.unreflectSpecial(method, declaringClass).bindTo(obj)
。invokeWithArguments(args) - 模块访问异常:如果遇到
(涉及java.lang.reflect.InaccessibleObjectException
),必须告知用户需要添加JVM启动参数java.lang.invoke
以允许反射访问。--add-opens java.base/java.lang.invoke=ALL-UNNAMED - Bean注册:对于没有Spring注解(如
)的接口,实现@Component
接口。在BeanDefinitionRegistryPostProcessor
方法中,使用postProcessBeanFactory
将生成的代理实例注册为Spring Bean。beanFactory.registerSingleton
Anti-Patterns
- 不要使用JDK动态代理(
),除非明确要求。Proxy.newProxyInstance - 不要在CGLIB代理中对默认方法使用
,这会导致错误。method.invoke(obj, args) - 不要假设目标接口有具体的实现类,代理对象本身就是实现。
Triggers
- cglib代理接口
- spring动态代理接口
- 处理接口default方法
- InaccessibleObjectException cglib