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.md
source content

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