通过Spring AOP引入新功能

问题描述

| 我正在使用Spring In Action(第3版)书来学习Spring。我在书中遇到了一个对我不起作用的例子。以下是详细信息: 我正在尝试使用Spring AOP在bean中引入新功能: 这是类结构: 器乐演奏者 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();
}
亲爱的选手类
package chapter4;

public class GracIoUsContestant implements Contestant {
    public void receiveAward() {
        System.out.println(\"Won a car worth 4K!\");
    }
}
我的春季配置文件名为“ spring-idol2.xml”,如下所示:
<?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>
我的Main方法如下所示:
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]”的原因?语法错误吗? 非常感谢你, 问候, 嘘     

解决方法

请注意,
<aop:config>
在应用方面之前会看到Bean,因此我想您不能在其他方面声明中使用
<aop:declare-parents>
引入的方法。 如果要检查ѭ9是否有效,可以执行以下操作:
Performer p1 = (Performer) context.getBean(\"ken\"); 
p1.perform();
((Contestant) p1).reveiveAward();
    ,我想你写的时候
<aop:aspect ref=\"ken\">
    ...
</aop:aspect>
您所说的是该方面是在名为“ ken”的bean中实现的。在您的示例中不是这种情况,方面位于bean \“ contestantDelegate \”中。所以我会尝试;
<aop:aspect ref=\"contestantDelegate\">
    ...
</aop:aspect>