如何让BeanPostProcessor生成的代理作用于实现类而非接口?
实现方案
你只需要调整BeanPostProcessor的判断逻辑,同时配置ProxyFactory使用CGLIB子类代理即可,不需要依赖上层接口。
核心改动点
- 把原来的接口实例判断替换为
@Service注解检测,覆盖所有标注了@Service的Bean - 为
ProxyFactory开启setProxyTargetClass(true)配置,强制使用CGLIB生成目标类的子类代理,无需依赖接口 - 移除绑定特定接口的逻辑,适配任意普通实现类
完整代码实现
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Service; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.AfterReturningAdvice; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; @Component public class MethodBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { // 筛选所有标注@Service的Bean if (AnnotationUtils.findAnnotation(bean.getClass(), Service.class) == null) { return bean; } ProxyFactory factory = new ProxyFactory(bean); // 开启CGLIB子类代理,无需依赖接口 factory.setProxyTargetClass(true); factory.addAdvice((AfterReturningAdvice) (returnValue, method, args, target) -> { // 筛选标注@Refreshable的方法 if (method.isAnnotationPresent(Refreshable.class)) { // Java 16以下版本替换为普通强转逻辑即可 if (returnValue instanceof RefreshableDto refreshableDto) { refreshableDto.copyId(); } } }); factory.setExposeProxy(true); return factory.getProxy(); } }
注意事项
- 被代理的
@Service类不能用final修饰,被代理的@Refreshable方法也不能用final修饰,否则CGLIB无法生成代理子类 - 单独设置的
setProxyTargetClass(true)优先级高于Spring全局AOP代理配置,不会受spring.aop.proxy-target-class参数影响
内容的提问来源于stack exchange,提问作者Karord
相关产品推荐
相关产品推荐

