Spring将参数设置为AOP方法

时间:2013-07-25 21:50:46

标签: java spring spring-aop

一切! 我无法解决AOP Spring的问题。我有一个班级

public class Minstrel {
public void singBefore(Knight knight) {
    System.out
            .println("Fa la la; Sir" + knight.getName() + " is so brave!");
}

public void singAfter(Knight knight) {
    System.out.println("Tee-hee-he; Sir" + knight.getName()
            + " did embark on a quest!");
}
}

此类的方法将对Knight类中的embarkOnQuest()方法做出反应。如何将骑士对象设置为参与singBefore(骑士骑士)和singAfter(骑士骑士)?它必须是XML文件? XML文件:

<bean id="grail" class="au.adelaide.knight_example.grail.HolyGrail" />

<bean id="quest" class="au.adelaide.knight_example.quest.HolyGrailQuest">
    <property name="grail" ref="grail" />
</bean>

<bean id="knight" class="au.adelaide.knight_example.knight.RoundTableKnight">
    <constructor-arg value="Arthur" />
    <property name="quest" ref="quest" />
</bean>

<bean id="minstrel" class="au.adelaide.knight_example.minstrel.Minstrel" />
<aop:config>
    <aop:aspect ref="minstrel">
        <aop:pointcut id="questPointcut"
            expression="execution(* *.embarkOnQuest(..))" />
        <aop:before method="singBefore" pointcut-ref="questPointcut" arg-names="knight" />
        <aop:after-returning method="singAfter"
            pointcut-ref="questPointcut" arg-names="knight" />
    </aop:aspect>
</aop:config>

Stacktrace是:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld' defined in class path resource [Beans.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': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.AspectJPointcutAdvisor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: knight [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:454)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
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:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
at au.adelaide.main.SpringInAction.main(SpringInAction.java:12)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.aop.aspectj.AspectJPointcutAdvisor#0': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.AspectJPointcutAdvisor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: knight [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1045)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:949)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
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:101)
at org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator.shouldSkip(AspectJAwareAdvisorAutoProxyCreator.java:103)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessBeforeInstantiation(AbstractAutoProxyCreator.java:276)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:890)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation(AbstractAutowireCapableBeanFactory.java:862)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:448)
... 10 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.AspectJPointcutAdvisor]: Constructor threw exception; nested exception is java.lang.IllegalArgumentException: warning no match for this type name: knight [Xlint:invalidAbsoluteTypeName]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:121)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:280)
... 25 more
Caused by: java.lang.IllegalArgumentException: warning no match for this type name: knight [Xlint:invalidAbsoluteTypeName]
at org.aspectj.weaver.tools.PointcutParser.parsePointcutExpression(PointcutParser.java:301)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:208)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.buildPointcutExpression(AspectJExpressionPointcut.java:194)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.checkReadyToMatch(AspectJExpressionPointcut.java:183)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getMethodMatcher(AspectJExpressionPointcut.java:169)
at org.springframework.aop.aspectj.AbstractAspectJAdvice.buildSafePointcut(AbstractAspectJAdvice.java:187)
at org.springframework.aop.aspectj.AspectJPointcutAdvisor.<init>(AspectJPointcutAdvisor.java:51)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 27 more

感谢您的回答。

2 个答案:

答案 0 :(得分:0)

尝试

<aop:pointcut id="questPointcut"
            expression="execution(* *.embarkOnQuest(..)) and this(knight)" />

在参数绑定表单中使用this poincut指示符。

请参阅http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/aop.html#aop-ataspectj-advice-params-names

答案 1 :(得分:0)

试试这个 -

...
<bean id="minstrel" class="com.springinaction.chapter01.knight.Minstrel"/>
   <aop:config>
      <aop:aspect ref="minstrel">
         <aop:pointcut id="questPointcut" expression="execution(* *.embarkOnQuest(..)) and target(bean)" />
         <aop:before method="singBefore" pointcut-ref="questPointcut" arg-names="bean" />
         <aop:after-returning method="singAfter" pointcut-ref="questPointcut" arg-names="bean" />
      </aop:aspect>
   </aop:config>
...   

这类似于 -

public class KnightOfTheRoundTable implements Knight {
   …
   private Minstrel minstrel;
   public void setMinstrel(Minstrel minstrel) {
      this.minstrel = minstrel;
   } 
   …
   public HolyGrail embarkOnQuest() throws QuestFailedException {
      minstrel.singBefore(this);
      HolyGrail grail = quest.embark();       
      minstrel.singAfter(this);

      return grail;
   }
}