Spring SPEL引用Bean报错EL1057E的解决求助
问题解决:SPEL表达式无法解析Spring Bean的错误
问题根源
你遇到的EL1057E: No bean resolver registered in the context to resolve access to bean 'validatorService'错误,核心原因是当前使用的SPEL上下文没有注册Spring Bean解析器。直接调用expression.getValue(args)时,SPEL只能识别方法参数,但无法解析@beanName这种Spring Bean引用语法。
解决方案
需要创建StandardEvaluationContext,并向其中注册Spring的BeanResolver,同时将方法参数绑定到上下文变量中。具体步骤如下:
1. 修改切面代码,配置SPEL上下文
在切面的checkEntity方法中,替换原有的SPEL执行逻辑,改为使用带Bean解析器的上下文:
@Component @Aspect public class CheckEntityAspect { private Logger logger = LoggerFactory.getLogger(CheckEntityAspect.class); private final ApplicationContext applicationContext; // 注入ApplicationContext,用于获取BeanResolver public CheckEntityAspect(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Before("execution(* *.*(..)) && @annotation(checkEntity)") public void checkEntity(JoinPoint joinPoint, CheckEntity checkEntity) { ExpressionParser elParser = new SpelExpressionParser(); Expression expression = elParser.parseExpression(checkEntity.keyPath()); // 创建标准SPEL上下文 StandardEvaluationContext context = new StandardEvaluationContext(); // 注册Spring Bean解析器,让SPEL能识别@beanName语法 context.setBeanResolver(new BeanFactoryResolver(applicationContext.getAutowireCapableBeanFactory())); // 自动绑定所有方法参数到SPEL变量(适配多参数场景) MethodSignature signature = (MethodSignature) joinPoint.getSignature(); String[] paramNames = signature.getParameterNames(); Object[] args = joinPoint.getArgs(); for (int i = 0; i < paramNames.length; i++) { context.setVariable(paramNames[i], args[i]); } try { // 执行SPEL表达式,调用Bean方法 expression.getValue(context); logger.info("颜色校验通过"); } catch (SpelEvaluationException e) { logger.error("SPEL表达式解析失败", e); throw new RuntimeException("校验失败", e); } catch (ColorIsNotRedException e) { logger.error("颜色不符合要求", e); throw e; } } }
2. 清理冗余配置
你的ColorIsRedValidatorService已经标注了@Service,Spring会自动扫描并注册该Bean,因此可以删除ColorBeanResolved配置类,避免Bean重复定义的潜在问题。
3. 关键说明
- BeanResolver注册:
BeanFactoryResolver是Spring提供的SPEL Bean解析器,它能根据Bean名称从Spring容器中获取对应的Bean实例,支持@beanName.method()的调用方式。 - 参数自动绑定:通过
MethodSignature获取参数名并绑定到上下文,无需手动逐个设置变量,适配任意参数数量的方法。
验证效果
修改后,当调用ColorService.checkColorIsRed("red")时,SPEL表达式@validatorService.isColorRed(#color)会正确调用ColorIsNotRedValidatorService的校验方法;如果传入非红色值,会抛出ColorIsNotRedException,实现预期的校验逻辑。
内容的提问来源于stack exchange,提问作者tm1701
相关产品推荐
相关产品推荐

