2011-05-23 64 views
4

我正在學習Spring使用Spring In Action(第3版)一書。我在書中遇到了一個不適合我的例子。以下是詳細介紹:Spring AOP引入新功能

我試圖使用Spring AOP在一個bean中引入新功能:

這裏是類結構:

  1. 器樂實現表演
  2. GraciousContestant實現參賽者

表演者接口

public interface Performer { 
    void perform(); 
} 

類器樂

package chapter4; 

public class Instrmentalist implements Performer { 
    public void perform() { 
     System.out.println("Sining hey hey, hey"); 
    } 
} 

參賽者接口

package chapter4; 

public interface Contestant { 
    void receiveAward(); 
} 

GraciousContestant類

package chapter4; 

public class GraciousContestant implements Contestant { 
    public void receiveAward() { 
     System.out.println("Won a car worth 4K!"); 
    } 
} 

我稱爲 「彈簧idol2.xml」 彈簧configuaration文件是如下:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 

    <bean id="ken" class="chapter4.Instrmentalist" /> 

    <bean id="contestantDelegate" class="chapter4.GraciousContestant" /> 

    <aop:config> 
     <aop:aspect> 
      <aop:declare-parents 
      types-matching="chapter4.Performer+" 
      implement-interface="chapter4.Contestant" 
      delegate-ref="contestantDelegate"/> 
     </aop:aspect> 

     <aop:aspect ref="ken"> 
      <aop:pointcut id="performance" 
        expression="execution(* chapter4.Performer.perform(..))" /> 
      <aop:after pointcut-ref="performance" method="receiveAward"/>  
    </aop:aspect> 
    </aop:config> 
</beans> 

我的主要方法是這樣的:

package chapter4; 

import org.springframework.context.support.AbstractApplicationContext; 
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class TestMain { 
    public static void main(String[] args) { 
     AbstractApplicationContext context = 
       new ClassPathXmlApplicationContext("/chapter4/spring-idol2.xml"); 

     Performer p1 = (Performer) context.getBean("ken");  
     p1.perform(); 
    } 
} 

什麼是應該被打印出來如下:

Sining hey hey, hey 
Won a car worth 4K! 

不過,我得到以下錯誤:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ken' defined in class path resource [chapter4/spring-idol2.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.DeclareParentsAdvisor#0': Cannot resolve reference to bean 'contestantDelegate' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contestantDelegate' defined in class path resource [chapter4/spring-idol2.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJAfterAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:900) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:455) 
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) 
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) 
    at chapter4.TestMain.main(TestMain.java:13) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.DeclareParentsAdvisor#0': Cannot resolve reference to bean 'contestantDelegate' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contestantDelegate' defined in class path resource [chapter4/spring-idol2.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJAfterAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:616) 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) 
    at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:86) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:100) 
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:107) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:278) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:848) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:820) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:446) 
    ... 10 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'contestantDelegate' defined in class path resource [chapter4/spring-idol2.xml]: BeanPostProcessor before instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJAfterAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:452) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322) 
    ... 28 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.aspectj.AspectJAfterAdvice] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:630) 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:198) 
    at org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans(BeanFactoryAdvisorRetrievalHelper.java:86) 
    at org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator.findCandidateAdvisors(AbstractAdvisorAutoProxyCreator.java:100) 
    at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:107) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:278) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:848) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:820) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:446) 
    ... 33 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Cannot create inner bean '(inner bean)' of type [org.springframework.aop.config.MethodLocatingFactoryBean] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:281) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:125) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:616) 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270) 
    ... 51 more 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:270) 
    ... 59 more 
Caused by: java.lang.IllegalArgumentException: Unable to locate method [receiveAward] on bean [ken] 
    at org.springframework.aop.config.MethodLocatingFactoryBean.setBeanFactory(MethodLocatingFactoryBean.java:75) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1440) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1408) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) 
    ... 61 more 

有人可以向我解釋爲什麼說「無法找到bean [ken]上的方法[receiveAward]」,即使我已經聲明瞭父項?語法錯了嗎?

非常感謝你,

問候,

庫什。

+0

其存在的異常:**無法找到方法[receiveAward]上豆[肯] ** – 2011-05-23 12:05:19

+0

@ d-現場,但該異常不應該存在,因爲我已經宣佈參賽者的家長。 – Khush 2011-05-23 12:29:38

回答

6

請注意,在應用方面之前,<aop:config>會看到bean,因此我猜想您不能在其他方面的聲明中使用由<aop:declare-parents>引入的方法。

如果你想檢查是否<aop:declare-parents>工作,你可以做這樣的事情:

Performer p1 = (Performer) context.getBean("ken"); 
p1.perform(); 
((Contestant) p1).reveiveAward(); 
+0

你的解釋也是有效的。非常感謝您花時間回答我的問題。我感謝您的幫助。 – Khush 2011-05-23 13:47:32

0

我認爲,當你寫

<aop:aspect ref="ken"> 
    ... 
</aop:aspect> 

什麼你說的是,一方面在執行名爲「ken」的bean。在你的例子中情況並非如此,該方面在bean「contestantDelegate」中。所以我會嘗試;

<aop:aspect ref="contestantDelegate"> 
    ... 
</aop:aspect> 
+0

但是,因爲我們宣佈參賽者爲父母,我們是否應該可以調用receiveAward方法?畢竟我們試圖使用Spring AOP來引入新功能? – Khush 2011-05-23 13:30:28