我有以下 bean 定义:
<bean id="kenny" class="com.springinaction.spingidol.performers.Instrumentalist"
p:song="'Disert Rose'" p:instrument="#{pianoInstrument}" />
<bean id="carl" class="com.springinaction.spingidol.performers.Instrumentalist"
p:song="#{kenny.song?.toUpperCase()}"
p:instrument="#{kenny.song.contains('Rose')?saxophoneInstrument:harmonicaInstrument}"/>
注意,carl
的 instrument
属性是基于 kenny
的 song
属性创建的。
只要我不使用 Spring AOP,当运行我的应用程序时,它完美地工作。
但是 当我添加一个引用 carl
bean 的方面时:
<aop:before method="takeSeats" pointcut="execution(* com.springinaction.spingidol.performers.Performer.perform(..))"/>
carl
和 kenny
bean 都实现了 Performer
接口(interface),因此出现以下异常:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'carl' defined in class path resource [spring-idol.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 6): Property or field 'song' cannot be found on object of type 'com.sun.proxy.$Proxy6' - maybe not public?
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at com.springinaction.spingidol.Main.main(Main.java:17)
Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 6): Property or field 'song' cannot be found on object of type 'com.sun.proxy.$Proxy6' - maybe not public?
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:146)
at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java:1362)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.evaluate(BeanDefinitionValueResolver.java:228)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:204)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1456)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
... 11 more
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 6): Property or field 'song' cannot be found on object of type 'com.sun.proxy.$Proxy6' - maybe not public?
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:215)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:85)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:78)
at org.springframework.expression.spel.ast.CompoundExpression.getValueRef(CompoundExpression.java:54)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:84)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:153)
at org.springframework.expression.spel.ast.Ternary.getValueInternal(Ternary.java:48)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:103)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:94)
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:143)
... 17 more
最佳答案
这是一个预期的行为——实际上 Spring 会为 kenny
bean 创建一个动态代理,动态代理将基于 Perfomer
接口(interface),它没有歌曲属性(没有歌曲的 getter 或 setter),因此是异常(exception)。一个修复可能是将歌曲的 getters 添加到 Performer
界面中,这应该对你很有效。
关于java - for bean 使用 spEL 的 Spring AOP 代理创建错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26366287/