Spring Boot启用AOP后@ConfigurationProperties转Java record代理报错如何处理
问题原因
这个报错是因为你定义的AOP切点表达式范围太宽泛,匹配到了标注@ConfigurationProperties的record类。Java record默认是final类型,而Spring CGLIB代理基于继承目标类实现,无法继承final类因此抛出异常。@ConfigurationProperties本身是纯配置承载类,不需要生成代理,只要把这类从切面的匹配规则中排除即可解决问题。
解决方案
方案1:优化切面切点规则(最推荐)
修改你的切面切点表达式,新增排除@ConfigurationProperties类的规则即可,示例如下:
@Aspect @Component public class CustomAspect { // 仅示例:原切点是匹配指定包下所有类 // @Pointcut("within(com.your.business.package..*)") // 修改后:匹配指定包下所有类,排除带@ConfigurationProperties注解的类 @Pointcut("within(com.your.business.package..*) && !@within(org.springframework.boot.context.properties.ConfigurationProperties)") public void pointcutRule() {} // 你的切面通知逻辑保持不变 @Before("pointcutRule()") public void beforeHandle(JoinPoint joinPoint) { // 原有逻辑 } }
方案2:全局配置跳过配置类代理
如果不想修改切点规则,也可以全局配置Spring AOP自动代理创建器,跳过所有@ConfigurationProperties类的代理生成:
import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AopSkipConfig { @Bean public BeanPostProcessor skipPropertiesProxyProcessor() { return new BeanPostProcessor() { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean.getClass().isAnnotationPresent(ConfigurationProperties.class)) { // 标记该类不需要被代理 AbstractAutoProxyCreator.skipTargetClass(bean.getClass()); } return bean; } }; } }
两种方案任选其一即可正常使用record类型的配置属性类。
内容的提问来源于stack exchange,提问作者Viktor Magyari
相关产品推荐
相关产品推荐

