You need to enable JavaScript to run this app. 添加自定义BeanPostProcessor后按实现类获取Bean抛出No qualifying bean异常
优惠活动
大模型
产品
解决方案
定价
更多

添加自定义BeanPostProcessor后按实现类获取Bean抛出No qualifying bean异常

异常产生原因

你当前使用的是JDK动态代理实现代理逻辑,JDK动态代理的核心特性是生成的代理对象仅实现目标类的所有接口,与目标实现类本身无继承关系。
你在CustomBeanProcessor的postProcessAfterInitialization方法中,将Spring原生生成的OrderImpl类型Bean直接替换为了JDK动态代理对象,此时Spring容器中存储的对应Bean实际类型为代理类,仅匹配Order接口类型,无法匹配OrderImpl实现类类型,因此调用context.getBean(OrderImpl.class)时会抛出NoSuchBeanDefinitionException异常。

解决方案

方案1(推荐):遵循面向接口编程规范

始终通过Order接口类型获取、注入Bean,无需修改现有代理逻辑,符合接口与实现分离的设计原则。

方案2:替换为CGLIB动态代理

如果必须通过OrderImpl实现类类型操作Bean,可以将JDK动态代理替换为CGLIB动态代理:
CGLIB代理通过继承目标实现类的方式生成代理对象,生成的代理类是OrderImpl的子类,可以匹配OrderImpl类型的查找。
你可以直接使用Spring内置的ProxyFactory简化改造,修改CustomBeanProcessor的postProcessAfterInitialization方法逻辑如下:

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    // 仅对标注了@Time注解的类/方法生成代理,可按需调整过滤逻辑
    List<Method> annotatedMethods = getAnnotatedMethods(bean.getClass().getMethods(), Time.class);
    if (annotatedMethods.isEmpty()) {
        return bean;
    }
    ProxyFactory proxyFactory = new ProxyFactory(bean);
    // 开启CGLIB代理,强制代理目标类而非接口
    proxyFactory.setProxyTargetClass(true);
    proxyFactory.addAdvice((MethodInterceptor) invocation -> {
        long timeBeforeInvoking = System.nanoTime();
        Object result = invocation.proceed();
        if (annotatedMethods.stream().anyMatch(m -> m.getName().equals(invocation.getMethod().getName()))) {
            System.out.println(System.nanoTime() - timeBeforeInvoking);
        }
        return result;
    });
    return proxyFactory.getProxy(bean.getClass().getClassLoader());
}

注意:CGLIB无法代理final修饰的类和final修饰的方法,使用前需确认目标实现类符合要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 07:45:02